]> git.uio.no Git - u/mrichter/AliRoot.git/blob - Vc/include/Vc/scalar/vector.h
update to Vc 0.7.3-dev
[u/mrichter/AliRoot.git] / Vc / include / Vc / scalar / vector.h
1 /*  This file is part of the Vc library.
2
3     Copyright (C) 2009-2012 Matthias Kretz <kretz@kde.org>
4
5     Vc is free software: you can redistribute it and/or modify
6     it under the terms of the GNU Lesser General Public License as
7     published by the Free Software Foundation, either version 3 of
8     the License, or (at your option) any later version.
9
10     Vc is distributed in the hope that it will be useful, but
11     WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with Vc.  If not, see <http://www.gnu.org/licenses/>.
17
18 */
19
20 #ifndef SCALAR_VECTOR_H
21 #define SCALAR_VECTOR_H
22
23 #include <assert.h>
24 #include <algorithm>
25 #include <cmath>
26
27 #ifdef _MSC_VER
28 #include <float.h>
29 #endif
30
31 #include "../common/memoryfwd.h"
32 #include "macros.h"
33 #include "types.h"
34 #include "mask.h"
35 #include "writemaskedvector.h"
36
37 namespace AliRoot {
38 namespace Vc
39 {
40 namespace Scalar
41 {
42     enum VectorAlignmentEnum { VectorAlignment = 4 };
43
44 template<typename T>
45 class Vector
46 {
47     friend class WriteMaskedVector<T>;
48     public:
49         typedef typename DetermineEntryType<T>::Type EntryType;
50     protected:
51         EntryType m_data;
52     public:
53         typedef Vc::Memory<Vector<T>, 1> Memory;
54         typedef Vector<unsigned int> IndexType;
55         typedef Scalar::Mask<1u> Mask;
56         typedef Vector<T> AsArg;
57
58         Vc_ALWAYS_INLINE EntryType &data() { return m_data; }
59         Vc_ALWAYS_INLINE EntryType data() const { return m_data; }
60
61         enum Constants { Size = 1 };
62
63         ///////////////////////////////////////////////////////////////////////////////////////////
64         // uninitialized
65         Vc_ALWAYS_INLINE Vector() {}
66
67         ///////////////////////////////////////////////////////////////////////////////////////////
68         // constants
69         Vc_ALWAYS_INLINE Vector(VectorSpecialInitializerZero::ZEnum) : m_data(0) {}
70         Vc_ALWAYS_INLINE Vector(VectorSpecialInitializerOne::OEnum) : m_data(1) {}
71         Vc_ALWAYS_INLINE Vector(VectorSpecialInitializerIndexesFromZero::IEnum) : m_data(0) {}
72         static Vc_ALWAYS_INLINE Vector Zero() { Vector r; r.m_data = 0; return r; }
73         static Vc_ALWAYS_INLINE Vector One() { Vector r; r.m_data = 1; return r; }
74         static Vc_ALWAYS_INLINE Vector IndexesFromZero() { return Zero(); }
75         static Vc_INTRINSIC_L Vector Random() Vc_INTRINSIC_R;
76
77         ///////////////////////////////////////////////////////////////////////////////////////////
78         // static_cast / copy ctor
79         template<typename OtherT> explicit Vc_ALWAYS_INLINE Vector(const Vector<OtherT> &x) : m_data(static_cast<EntryType>(x.data())) {}
80
81         // implicit cast
82         template<typename OtherT> Vc_ALWAYS_INLINE_L Vector &operator=(const Vector<OtherT> &x) Vc_ALWAYS_INLINE_R;
83
84         // copy assignment
85         Vc_ALWAYS_INLINE Vector &operator=(Vector v) { m_data = v.data(); return *this; }
86
87         ///////////////////////////////////////////////////////////////////////////////////////////
88         // broadcast
89         explicit Vc_ALWAYS_INLINE Vector(EntryType x) : m_data(x) {}
90         template<typename TT> Vc_ALWAYS_INLINE Vector(TT x, VC_EXACT_TYPE(TT, EntryType, void *) = 0) : m_data(x) {}
91         Vc_ALWAYS_INLINE Vector &operator=(EntryType a) { m_data = a; return *this; }
92
93         ///////////////////////////////////////////////////////////////////////////////////////////
94         // load ctors
95         explicit Vc_ALWAYS_INLINE Vector(const EntryType *x) : m_data(x[0]) {}
96         template<typename A> Vc_ALWAYS_INLINE Vector(const EntryType *x, A) : m_data(x[0]) {}
97         template<typename Other> explicit Vc_ALWAYS_INLINE Vector(const Other *x) : m_data(x[0]) {}
98         template<typename Other, typename A> Vc_ALWAYS_INLINE Vector(const Other *x, A) : m_data(x[0]) {}
99
100         ///////////////////////////////////////////////////////////////////////////////////////////
101         // expand 1 float_v to 2 double_v                 XXX rationale? remove it for release? XXX
102         template<typename OtherT> Vc_ALWAYS_INLINE void expand(Vector<OtherT> *x) const { x->data() = static_cast<OtherT>(m_data); }
103         template<typename OtherT> explicit Vc_ALWAYS_INLINE Vector(const Vector<OtherT> *a) : m_data(static_cast<EntryType>(a->data())) {}
104
105         ///////////////////////////////////////////////////////////////////////////////////////////
106         // zeroing
107         Vc_ALWAYS_INLINE void setZero() { m_data = 0; }
108         Vc_ALWAYS_INLINE void setZero(Mask k) { if (k) m_data = 0; }
109
110         Vc_INTRINSIC_L void setQnan() Vc_INTRINSIC_R;
111         Vc_INTRINSIC_L void setQnan(Mask m) Vc_INTRINSIC_R;
112
113         ///////////////////////////////////////////////////////////////////////////////////////////
114         // load member functions
115         template<typename Other> Vc_ALWAYS_INLINE void load(const Other *mem) { m_data = mem[0]; }
116         template<typename Other, typename A> Vc_ALWAYS_INLINE void load(const Other *mem, A) { m_data = mem[0]; }
117         template<typename Other> Vc_ALWAYS_INLINE void load(const Other *mem, Mask m) { if (m.data()) m_data = mem[0]; }
118
119         Vc_ALWAYS_INLINE void load(const EntryType *mem) { m_data = mem[0]; }
120         template<typename A> Vc_ALWAYS_INLINE void load(const EntryType *mem, A) { m_data = mem[0]; }
121         Vc_ALWAYS_INLINE void load(const EntryType *mem, Mask m) { if (m.data()) m_data = mem[0]; }
122
123         ///////////////////////////////////////////////////////////////////////////////////////////
124         // stores
125         Vc_ALWAYS_INLINE void store(EntryType *mem) const { mem[0] = m_data; }
126         Vc_ALWAYS_INLINE void store(EntryType *mem, Mask m) const { if (m.data()) mem[0] = m_data; }
127         template<typename A> Vc_ALWAYS_INLINE void store(EntryType *mem, A) const { store(mem); }
128         template<typename A> Vc_ALWAYS_INLINE void store(EntryType *mem, Mask m, A) const { store(mem, m); }
129
130         ///////////////////////////////////////////////////////////////////////////////////////////
131         // swizzles
132         Vc_INTRINSIC const Vector<T> &abcd() const { return *this; }
133         Vc_INTRINSIC const Vector<T>  cdab() const { return *this; }
134         Vc_INTRINSIC const Vector<T>  badc() const { return *this; }
135         Vc_INTRINSIC const Vector<T>  aaaa() const { return *this; }
136         Vc_INTRINSIC const Vector<T>  bbbb() const { return *this; }
137         Vc_INTRINSIC const Vector<T>  cccc() const { return *this; }
138         Vc_INTRINSIC const Vector<T>  dddd() const { return *this; }
139         Vc_INTRINSIC const Vector<T>  bcad() const { return *this; }
140         Vc_INTRINSIC const Vector<T>  bcda() const { return *this; }
141         Vc_INTRINSIC const Vector<T>  dabc() const { return *this; }
142         Vc_INTRINSIC const Vector<T>  acbd() const { return *this; }
143         Vc_INTRINSIC const Vector<T>  dbca() const { return *this; }
144         Vc_INTRINSIC const Vector<T>  dcba() const { return *this; }
145
146         ///////////////////////////////////////////////////////////////////////////////////////////
147         // gathers
148         template<typename IndexT> Vc_ALWAYS_INLINE Vector(const EntryType *array, const IndexT *indexes) : m_data(array[indexes[0]]) {}
149         template<typename IndexT> Vc_ALWAYS_INLINE Vector(const EntryType *array, Vector<IndexT> indexes) : m_data(array[indexes[0]]) {}
150         template<typename IndexT> Vc_ALWAYS_INLINE Vector(const EntryType *array, IndexT indexes, Mask m) : m_data(m.data() ? array[indexes[0]] : 0) {}
151         template<typename S1, typename IT> Vc_ALWAYS_INLINE Vector(const S1 *array, const EntryType S1::* member1, IT indexes, Mask mask = Mask(true))
152             : m_data(mask.data() ? (&array[indexes[0]])->*(member1) : 0) {}
153         template<typename S1, typename S2, typename IT> Vc_ALWAYS_INLINE Vector(const S1 *array, const S2 S1::* member1,
154                 const EntryType S2::* member2, IT indexes, Mask mask = Mask(true))
155             : m_data(mask.data() ? array[indexes[0]].*(member1).*(member2) : 0) {}
156         template<typename S1, typename IT1, typename IT2> Vc_ALWAYS_INLINE Vector(const S1 *array, const EntryType *const S1::* ptrMember1,
157                 IT1 outerIndex, IT2 innerIndex, Mask mask = Mask(true))
158             : m_data(mask.data() ? (array[outerIndex[0]].*(ptrMember1))[innerIndex[0]] : 0) {}
159
160         template<typename IT> Vc_ALWAYS_INLINE void gather(const EntryType *array, IT indexes, Mask mask = Mask(true))
161             { if (mask.data()) m_data = array[indexes[0]]; }
162         template<typename S1, typename IT> Vc_ALWAYS_INLINE void gather(const S1 *array, const EntryType S1::* member1, IT indexes, Mask mask = Mask(true))
163             { if (mask.data()) m_data = (&array[indexes[0]])->*(member1); }
164         template<typename S1, typename S2, typename IT> Vc_ALWAYS_INLINE void gather(const S1 *array, const S2 S1::* member1,
165                 const EntryType S2::* member2, IT indexes, Mask mask = Mask(true))
166             { if (mask.data()) m_data = array[indexes[0]].*(member1).*(member2); }
167         template<typename S1, typename IT1, typename IT2> Vc_ALWAYS_INLINE void gather(const S1 *array, const EntryType *const S1::* ptrMember1,
168                 IT1 outerIndex, IT2 innerIndex, Mask mask = Mask(true))
169             { if (mask.data()) m_data = (array[outerIndex[0]].*(ptrMember1))[innerIndex[0]]; }
170
171         ///////////////////////////////////////////////////////////////////////////////////////////
172         // scatters
173         Vc_ALWAYS_INLINE void scatter(EntryType *array, const Vector<unsigned int> &indexes, Mask m = Mask(true)) const { if (m.data()) array[indexes[0]] = m_data; }
174         template<typename S1> Vc_ALWAYS_INLINE void scatter(S1 *array, EntryType S1::* member, const Vector<unsigned int> &indexes, Mask m = Mask(true)) const {
175             if (m.data()) array[indexes[0]].*(member) = m_data;
176         }
177         template<typename S1, typename S2> Vc_ALWAYS_INLINE void scatter(S1 *array, S2 S1::* member1, EntryType S2::* member2,
178                 const Vector<unsigned int> &indexes, Mask m = Mask(true)) const {
179             if (m.data()) array[indexes[0]].*(member1).*(member2) = m_data;
180         }
181
182         Vc_ALWAYS_INLINE void scatter(EntryType *array, const Vector<unsigned short> &indexes, Mask m = Mask(true)) const { if (m.data()) array[indexes[0]] = m_data; }
183         template<typename S1> Vc_ALWAYS_INLINE void scatter(S1 *array, EntryType S1::* member, const Vector<unsigned short> &indexes, Mask m = Mask(true)) const {
184             if (m.data()) array[indexes[0]].*(member) = m_data;
185         }
186         template<typename S1, typename S2> Vc_ALWAYS_INLINE void scatter(S1 *array, S2 S1::* member1, EntryType S2::* member2,
187                 const Vector<unsigned short> &indexes, Mask m = Mask(true)) const {
188             if (m.data()) array[indexes[0]].*(member1).*(member2) = m_data;
189         }
190
191         //prefix
192         Vc_ALWAYS_INLINE Vector &operator++() { ++m_data; return *this; }
193         Vc_ALWAYS_INLINE Vector &operator--() { --m_data; return *this; }
194         //postfix
195         Vc_ALWAYS_INLINE Vector operator++(int) { return m_data++; }
196         Vc_ALWAYS_INLINE Vector operator--(int) { return m_data--; }
197
198         Vc_ALWAYS_INLINE EntryType &operator[](size_t index) {
199             assert(index == 0); if(index) {}
200             return m_data;
201         }
202
203         Vc_ALWAYS_INLINE EntryType operator[](size_t index) const {
204             assert(index == 0); if(index) {}
205             return m_data;
206         }
207
208         Vc_ALWAYS_INLINE Vector operator~() const { return Vector(~m_data); }
209         Vc_ALWAYS_INLINE Vector<typename NegateTypeHelper<T>::Type> operator-() const { return Vector<typename NegateTypeHelper<T>::Type>(-m_data); }
210         Vc_INTRINSIC Vector Vc_PURE operator+() const { return *this; }
211
212 #define OPshift(symbol) \
213         Vc_ALWAYS_INLINE Vector &operator symbol##=(const Vector<T> &x) { m_data symbol##= x.m_data; return *this; } \
214         Vc_ALWAYS_INLINE Vector &operator symbol##=(EntryType x) { return operator symbol##=(Vector(x)); } \
215         Vc_ALWAYS_INLINE Vector operator symbol(const Vector<T> &x) const { return Vector<T>(m_data symbol x.m_data); }
216 #define OPshift_int(symbol) \
217         Vc_ALWAYS_INLINE Vector operator symbol(int x) const { return Vector(m_data symbol x); }
218 #define OP(symbol) \
219         OPshift(symbol) \
220         template<typename TT> Vc_ALWAYS_INLINE VC_EXACT_TYPE(TT, EntryType, Vector) operator symbol(TT x) const { return operator symbol(Vector(x)); }
221 #define OPcmp(symbol) \
222         Vc_ALWAYS_INLINE Mask operator symbol(const Vector<T> &x) const { return Mask(m_data symbol x.m_data); } \
223         template<typename TT> Vc_ALWAYS_INLINE VC_EXACT_TYPE(TT, EntryType, Mask) operator symbol(TT x) const { return Mask(m_data symbol x); }
224
225         VC_ALL_ARITHMETICS(OP)
226         VC_ALL_BINARY(OP)
227         VC_ALL_SHIFTS(OPshift)
228         VC_ALL_SHIFTS(OPshift_int)
229         VC_ALL_COMPARES(OPcmp)
230 #undef OP
231 #undef OPcmp
232 #undef OPshift
233 #undef OPshift_int
234         Vc_INTRINSIC_L Vc_PURE_L Mask isNegative() const Vc_PURE_R Vc_INTRINSIC_R;
235
236         Vc_ALWAYS_INLINE void fusedMultiplyAdd(const Vector<T> &factor, const Vector<T> &summand) {
237             m_data = m_data * factor.data() + summand.data();
238         }
239
240         Vc_ALWAYS_INLINE void assign(const Vector<T> &v, const Mask &m) {
241           if (m.data()) m_data = v.m_data;
242         }
243
244         template<typename V2> Vc_ALWAYS_INLINE V2 staticCast() const { return V2(static_cast<typename V2::EntryType>(m_data)); }
245         template<typename V2> Vc_ALWAYS_INLINE V2 reinterpretCast() const {
246             typedef typename V2::EntryType AliasT2 Vc_MAY_ALIAS;
247             return V2(*reinterpret_cast<const AliasT2 *>(&m_data));
248         }
249
250         Vc_ALWAYS_INLINE WriteMaskedVector<T> operator()(Mask m) { return WriteMaskedVector<T>(this, m); }
251
252         Vc_ALWAYS_INLINE bool pack(Mask &m1, Vector<T> &v2, Mask &m2) {
253             if (!m1.data() && m2.data()) {
254                 m_data = v2.m_data;
255                 m1 = true;
256                 m2 = false;
257                 return true;
258             }
259             return m1;
260         }
261
262         Vc_ALWAYS_INLINE EntryType min() const { return m_data; }
263         Vc_ALWAYS_INLINE EntryType max() const { return m_data; }
264         Vc_ALWAYS_INLINE EntryType product() const { return m_data; }
265         Vc_ALWAYS_INLINE EntryType sum() const { return m_data; }
266         Vc_ALWAYS_INLINE EntryType min(Mask) const { return m_data; }
267         Vc_ALWAYS_INLINE EntryType max(Mask) const { return m_data; }
268         Vc_ALWAYS_INLINE EntryType product(Mask) const { return m_data; }
269         Vc_ALWAYS_INLINE EntryType sum(Mask m) const { if (m) return m_data; return static_cast<EntryType>(0); }
270
271         Vc_INTRINSIC Vector shifted(int amount) const { return amount == 0 ? *this : Zero(); }
272         Vc_INTRINSIC Vector rotated(int) const { return *this; }
273         Vector sorted() const { return *this; }
274
275         template<typename F> void callWithValuesSorted(F &f) {
276             f(m_data);
277         }
278
279         template<typename F> Vc_INTRINSIC void call(const F &f) const {
280             f(m_data);
281         }
282         template<typename F> Vc_INTRINSIC void call(F &f) const {
283             f(m_data);
284         }
285
286         template<typename F> Vc_INTRINSIC void call(const F &f, Mask mask) const {
287             if (mask) {
288                 f(m_data);
289             }
290         }
291         template<typename F> Vc_INTRINSIC void call(F &f, Mask mask) const {
292             if (mask) {
293                 f(m_data);
294             }
295         }
296
297         template<typename F> Vc_INTRINSIC Vector apply(const F &f) const {
298             return Vector(f(m_data));
299         }
300         template<typename F> Vc_INTRINSIC Vector apply(F &f) const {
301             return Vector(f(m_data));
302         }
303
304         template<typename F> Vc_INTRINSIC Vector apply(const F &f, Mask mask) const {
305             if (mask) {
306                 return Vector(f(m_data));
307             } else {
308                 return *this;
309             }
310         }
311         template<typename F> Vc_INTRINSIC Vector apply(F &f, Mask mask) const {
312             if (mask) {
313                 return Vector(f(m_data));
314             } else {
315                 return *this;
316             }
317         }
318
319         template<typename IndexT> Vc_INTRINSIC void fill(EntryType (&f)(IndexT)) {
320             m_data = f(0);
321         }
322         Vc_INTRINSIC void fill(EntryType (&f)()) {
323             m_data = f();
324         }
325
326         Vc_INTRINSIC_L Vector copySign(Vector reference) const Vc_INTRINSIC_R;
327         Vc_INTRINSIC_L Vector exponent() const Vc_INTRINSIC_R;
328 };
329
330 typedef Vector<double>         double_v;
331 typedef Vector<float>          float_v;
332 typedef Vector<sfloat>         sfloat_v;
333 typedef Vector<int>            int_v;
334 typedef Vector<unsigned int>   uint_v;
335 typedef Vector<short>          short_v;
336 typedef Vector<unsigned short> ushort_v;
337 typedef double_v::Mask double_m;
338 typedef float_v::Mask float_m;
339 typedef sfloat_v::Mask sfloat_m;
340 typedef int_v::Mask int_m;
341 typedef uint_v::Mask uint_m;
342 typedef short_v::Mask short_m;
343 typedef ushort_v::Mask ushort_m;
344
345 template<typename T> class SwizzledVector : public Vector<T> {};
346
347 #ifdef _MSC_VER
348   template<typename T> static Vc_ALWAYS_INLINE void forceToRegisters(const Vector<T> &) {
349   }
350 #else
351   template<typename T> static Vc_ALWAYS_INLINE void forceToRegisters(const Vector<T> &x01) {
352       __asm__ __volatile__(""::"r"(x01.data()));
353   }
354   template<> Vc_ALWAYS_INLINE void forceToRegisters(const Vector<float> &x01) {
355       __asm__ __volatile__(""::"x"(x01.data()));
356   }
357   template<> Vc_ALWAYS_INLINE void forceToRegisters(const Vector<double> &x01) {
358       __asm__ __volatile__(""::"x"(x01.data()));
359   }
360 #endif
361   template<typename T1, typename T2> static Vc_ALWAYS_INLINE void forceToRegisters(
362       const Vector<T1> &x01, const Vector<T2> &x02) {
363       forceToRegisters(x01);
364       forceToRegisters(x02);
365   }
366   template<typename T1, typename T2, typename T3> static Vc_ALWAYS_INLINE void forceToRegisters(
367         const Vector<T1>  &,  const Vector<T2>  &, const Vector<T3>  &) {}
368   template<typename T1, typename T2, typename T3, typename T4> static Vc_ALWAYS_INLINE void forceToRegisters(
369         const Vector<T1>  &,  const Vector<T2>  &,
370         const Vector<T3>  &,  const Vector<T4>  &) {}
371   template<typename T1, typename T2, typename T3, typename T4, typename T5>
372     static Vc_ALWAYS_INLINE void forceToRegisters(
373         const Vector<T1>  &,  const Vector<T2>  &,
374         const Vector<T3>  &,  const Vector<T4>  &,
375         const Vector<T5>  &) {}
376   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
377     static Vc_ALWAYS_INLINE void forceToRegisters(
378         const Vector<T1>  &,  const Vector<T2>  &,
379         const Vector<T3>  &,  const Vector<T4>  &,
380         const Vector<T5>  &,  const Vector<T6>  &) {}
381   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
382     typename T7>
383     static Vc_ALWAYS_INLINE void forceToRegisters(
384         const Vector<T1>  &,  const Vector<T2>  &,
385         const Vector<T3>  &,  const Vector<T4>  &,
386         const Vector<T5>  &,  const Vector<T6>  &,
387         const Vector<T7>  &) {}
388   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
389     typename T7, typename T8>
390     static Vc_ALWAYS_INLINE void forceToRegisters(
391         const Vector<T1>  &,  const Vector<T2>  &,
392         const Vector<T3>  &,  const Vector<T4>  &,
393         const Vector<T5>  &,  const Vector<T6>  &,
394         const Vector<T7>  &,  const Vector<T8>  &) {}
395   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
396     typename T7, typename T8, typename T9>
397     static Vc_ALWAYS_INLINE void forceToRegisters(
398         const Vector<T1>  &,  const Vector<T2>  &,
399         const Vector<T3>  &,  const Vector<T4>  &,
400         const Vector<T5>  &,  const Vector<T6>  &,
401         const Vector<T7>  &,  const Vector<T8>  &,
402         const Vector<T9>  &) {}
403   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
404     typename T7, typename T8, typename T9, typename T10>
405     static Vc_ALWAYS_INLINE void forceToRegisters(
406         const Vector<T1>  &, const Vector<T2>  &,
407         const Vector<T3>  &, const Vector<T4>  &,
408         const Vector<T5>  &, const Vector<T6>  &,
409         const Vector<T7>  &, const Vector<T8>  &,
410         const Vector<T9>  &, const Vector<T10> &) {}
411   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
412     typename T7, typename T8, typename T9, typename T10, typename T11>
413     static Vc_ALWAYS_INLINE void forceToRegisters(
414         const Vector<T1>  &, const Vector<T2>  &,
415         const Vector<T3>  &, const Vector<T4>  &,
416         const Vector<T5>  &, const Vector<T6>  &,
417         const Vector<T7>  &, const Vector<T8>  &,
418         const Vector<T9>  &, const Vector<T10> &,
419         const Vector<T11> &) {}
420   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
421     typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
422     static Vc_ALWAYS_INLINE void forceToRegisters(
423         const Vector<T1>  &, const Vector<T2>  &,
424         const Vector<T3>  &, const Vector<T4>  &,
425         const Vector<T5>  &, const Vector<T6>  &,
426         const Vector<T7>  &, const Vector<T8>  &,
427         const Vector<T9>  &, const Vector<T10> &,
428         const Vector<T11> &, const Vector<T12> &) {}
429   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
430     typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13>
431     static Vc_ALWAYS_INLINE void forceToRegisters(
432         const Vector<T1>  &, const Vector<T2>  &,
433         const Vector<T3>  &, const Vector<T4>  &,
434         const Vector<T5>  &, const Vector<T6>  &,
435         const Vector<T7>  &, const Vector<T8>  &,
436         const Vector<T9>  &, const Vector<T10> &,
437         const Vector<T11> &, const Vector<T12> &,
438         const Vector<T13> &) {}
439   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
440     typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13,
441     typename T14> static Vc_ALWAYS_INLINE void forceToRegisters(
442         const Vector<T1>  &, const Vector<T2>  &,
443         const Vector<T3>  &, const Vector<T4>  &,
444         const Vector<T5>  &, const Vector<T6>  &,
445         const Vector<T7>  &, const Vector<T8>  &,
446         const Vector<T9>  &, const Vector<T10> &,
447         const Vector<T11> &, const Vector<T12> &,
448         const Vector<T13> &, const Vector<T14> &) {}
449   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
450     typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13,
451     typename T14, typename T15> static Vc_ALWAYS_INLINE void forceToRegisters(
452         const Vector<T1>  &, const Vector<T2>  &,
453         const Vector<T3>  &, const Vector<T4>  &,
454         const Vector<T5>  &, const Vector<T6>  &,
455         const Vector<T7>  &, const Vector<T8>  &,
456         const Vector<T9>  &, const Vector<T10> &,
457         const Vector<T11> &, const Vector<T12> &,
458         const Vector<T13> &, const Vector<T14> &,
459         const Vector<T15> &) {}
460   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
461     typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13,
462     typename T14, typename T15, typename T16> static Vc_ALWAYS_INLINE void forceToRegisters(
463         const Vector<T1>  &, const Vector<T2>  &,
464         const Vector<T3>  &, const Vector<T4>  &,
465         const Vector<T5>  &, const Vector<T6>  &,
466         const Vector<T7>  &, const Vector<T8>  &,
467         const Vector<T9>  &, const Vector<T10> &,
468         const Vector<T11> &, const Vector<T12> &,
469         const Vector<T13> &, const Vector<T14> &,
470         const Vector<T15> &, const Vector<T16> &) {}
471
472 } // namespace Scalar
473 } // namespace Vc
474 } // namespace AliRoot
475
476 #include "vector.tcc"
477 #include "math.h"
478 #include "undomacros.h"
479
480 #endif // SCALAR_VECTOR_H