ROOT  6.06/09
Reference Guide
memorybase.h
Go to the documentation of this file.
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 VC_COMMON_MEMORYBASE_H
21 #define VC_COMMON_MEMORYBASE_H
22 
23 #include <assert.h>
24 #include "macros.h"
25 
26 namespace ROOT {
27 namespace Vc
28 {
29 
30 #if __cplusplus >= 201103 || defined(VC_MSVC)
31 #define VC_DECLTYPE(T1, op, T2) decltype(T1() op T2())
32 #elif defined(VC_OPEN64) || (defined(VC_GCC) && VC_GCC < 0x40300)
33 #define VC_DECLTYPE(T1, op, T2) T1
34 #else
35 namespace
36 {
37  struct one { char x; };
38  struct two { one x, y; };
39  template<typename T1, typename T2> struct DecltypeHelper
40  {
41  static one test(const T1 &) { return one(); }
42  static two test(const T2 &) { return two(); }
43  //static void test(...) {}
44  };
45  template<typename T1> struct DecltypeHelper<T1, T1>
46  {
47  static one test(const T1 &) { return one(); }
48  //static void test(...) {}
49  };
50  template<typename T1, typename T2, size_t ToSelect> struct Decltype { typedef T1 Value; };
51  template<typename T1, typename T2> struct Decltype<T1, T2, sizeof(one)> { typedef T1 Value; };
52  template<typename T1, typename T2> struct Decltype<T1, T2, sizeof(two)> { typedef T2 Value; };
53 #ifdef VC_CLANG
54  // this special case is only necessary to silence a warning (which is rather a note that clang
55  // did the expected optimization):
56  // warning: variable 'SOME_PTR' is not needed and will not be emitted [-Wunneeded-internal-declaration]
57  // Then again, I don't remember why the SOME_PTR hack was necessary in the first place - some
58  // strange compiler quirk...
59 #define VC_DECLTYPE(T1, op, T2) typename Decltype<T1, T2, sizeof(DecltypeHelper<T1, T2>::test(T1() op T2()))>::Value
60 #else
61  static const void *SOME_PTR;
62 #define VC_DECLTYPE(T1, op, T2) typename Decltype<T1, T2, sizeof(DecltypeHelper<T1, T2>::test(*static_cast<const T1*>(SOME_PTR) op *static_cast<const T2*>(SOME_PTR)))>::Value
63 #endif
64 } // anonymous namespace
65 #endif
66 
67 #define VC_MEM_OPERATOR_EQ(op) \
68  template<typename T> \
69  Vc_ALWAYS_INLINE VectorPointerHelper<V, A> &operator op##=(const T &x) { \
70  const V result = V(m_ptr, Internal::FlagObject<A>::the()) op x; \
71  result.store(m_ptr, Internal::FlagObject<A>::the()); \
72  return *this; \
73  }
74 
75 /**
76  * Helper class for the Memory::vector(size_t) class of functions.
77  *
78  * You will never need to directly make use of this class. It is an implementation detail of the
79  * Memory API.
80  *
81  * \headerfile memorybase.h <Vc/Memory>
82  */
83 template<typename V, typename A> class VectorPointerHelperConst
84 {
85  typedef typename V::EntryType EntryType;
86  typedef typename V::Mask Mask;
87  public:
88  const EntryType *const m_ptr;
89 
90  explicit VectorPointerHelperConst(const EntryType *ptr) : m_ptr(ptr) {}
91 
92  /**
93  * Cast to \p V operator.
94  *
95  * This function allows to assign this object to any object of type \p V.
96  */
97  Vc_ALWAYS_INLINE Vc_PURE operator const V() const { return V(m_ptr, Internal::FlagObject<A>::the()); }
98 };
99 
100 /**
101  * Helper class for the Memory::vector(size_t) class of functions.
102  *
103  * You will never need to directly make use of this class. It is an implementation detail of the
104  * Memory API.
105  *
106  * \headerfile memorybase.h <Vc/Memory>
107  */
108 template<typename V, typename A> class VectorPointerHelper
109 {
110  typedef typename V::EntryType EntryType;
111  typedef typename V::Mask Mask;
112  public:
113  EntryType *const m_ptr;
114 
115  explicit VectorPointerHelper(EntryType *ptr) : m_ptr(ptr) {}
116 
117  /**
118  * Cast to \p V operator.
119  *
120  * This function allows to assign this object to any object of type \p V.
121  */
122  Vc_ALWAYS_INLINE Vc_PURE operator const V() const { return V(m_ptr, Internal::FlagObject<A>::the()); }
123 
124  template<typename T>
126  V v;
127  v = x;
128  v.store(m_ptr, Internal::FlagObject<A>::the());
129  return *this;
130  }
131 
134 };
135 #undef VC_MEM_OPERATOR_EQ
136 
137 #define VC_VPH_OPERATOR(op) \
138 template<typename V1, typename A1, typename V2, typename A2> \
139 VC_DECLTYPE(V1, op, V2) operator op(const VectorPointerHelper<V1, A1> &x, const VectorPointerHelper<V2, A2> &y) { \
140  return V1(x.m_ptr, Internal::FlagObject<A1>::the()) op V2(y.m_ptr, Internal::FlagObject<A2>::the()); \
141 }
145 #undef VC_VPH_OPERATOR
146 
147 template<typename V, typename Parent, int Dimension, typename RowMemory> class MemoryDimensionBase;
148 template<typename V, typename Parent, typename RowMemory> class MemoryDimensionBase<V, Parent, 1, RowMemory> // {{{1
149 {
150  private:
151  Parent *p() { return static_cast<Parent *>(this); }
152  const Parent *p() const { return static_cast<const Parent *>(this); }
153  public:
154  /**
155  * The type of the scalar entries in the array.
156  */
157  typedef typename V::EntryType EntryType;
158 
159  /**
160  * Returns a pointer to the start of the allocated memory.
161  */
162  Vc_ALWAYS_INLINE Vc_PURE EntryType *entries() { return &p()->m_mem[0]; }
163  /// Const overload of the above function.
164  Vc_ALWAYS_INLINE Vc_PURE const EntryType *entries() const { return &p()->m_mem[0]; }
165 
166  /**
167  * Returns the \p i-th scalar value in the memory.
168  */
169  Vc_ALWAYS_INLINE Vc_PURE EntryType &scalar(size_t i) { return entries()[i]; }
170  /// Const overload of the above function.
171  Vc_ALWAYS_INLINE Vc_PURE const EntryType scalar(size_t i) const { return entries()[i]; }
172 
173  /**
174  * Cast operator to the scalar type. This allows to use the object very much like a standard
175  * C array.
176  */
177  Vc_ALWAYS_INLINE Vc_PURE operator EntryType*() { return entries(); }
178  /// Const overload of the above function.
179  Vc_ALWAYS_INLINE Vc_PURE operator const EntryType*() const { return entries(); }
180 
181  // omit operator[] because the EntryType* cast operator suffices, for dox it makes sense to
182  // show it, though because it helps API discoverability.
183 #ifdef DOXYGEN
184  /**
185  * Returns the \p i-th scalar value in the memory.
186  */
187  inline EntryType &operator[](size_t i);
188  /// Const overload of the above function.
189  inline const EntryType &operator[](size_t i) const;
190 #endif
191 
192  /**
193  * Uses a vector gather to combine the entries at the indexes in \p i into the returned
194  * vector object.
195  *
196  * \param i An integer vector. It determines the entries to be gathered.
197  * \returns A vector object. Modification of this object will not modify the values in
198  * memory.
199  *
200  * \warning The API of this function might change in future versions of Vc to additionally
201  * support scatters.
202  */
203  template<typename IndexT> Vc_ALWAYS_INLINE Vc_PURE V operator[](Vector<IndexT> i) const
204  {
205  return V(entries(), i);
206  }
207 };
208 template<typename V, typename Parent, typename RowMemory> class MemoryDimensionBase<V, Parent, 2, RowMemory> // {{{1
209 {
210  private:
211  Parent *p() { return static_cast<Parent *>(this); }
212  const Parent *p() const { return static_cast<const Parent *>(this); }
213  public:
214  /**
215  * The type of the scalar entries in the array.
216  */
217  typedef typename V::EntryType EntryType;
218 
219  static _VC_CONSTEXPR size_t rowCount() { return Parent::RowCount; }
220 
221  /**
222  * Returns a pointer to the start of the allocated memory.
223  */
224  Vc_ALWAYS_INLINE Vc_PURE EntryType *entries(size_t x = 0) { return &p()->m_mem[x][0]; }
225  /// Const overload of the above function.
226  Vc_ALWAYS_INLINE Vc_PURE const EntryType *entries(size_t x = 0) const { return &p()->m_mem[x][0]; }
227 
228  /**
229  * Returns the \p i,j-th scalar value in the memory.
230  */
231  Vc_ALWAYS_INLINE Vc_PURE EntryType &scalar(size_t i, size_t j) { return entries(i)[j]; }
232  /// Const overload of the above function.
233  Vc_ALWAYS_INLINE Vc_PURE const EntryType scalar(size_t i, size_t j) const { return entries(i)[j]; }
234 
235  /**
236  * Returns the \p i-th row in the memory.
237  */
238  Vc_ALWAYS_INLINE Vc_PURE RowMemory &operator[](size_t i) {
239  return RowMemory::fromRawData(entries(i));
240  }
241  /// Const overload of the above function.
242  Vc_ALWAYS_INLINE Vc_PURE const RowMemory &operator[](size_t i) const {
243  return RowMemory::fromRawData(const_cast<EntryType *>(entries(i)));
244  }
245 
246  /**
247  * \return the number of rows in the array.
248  *
249  * \note This function can be eliminated by an optimizing compiler.
250  */
251  Vc_ALWAYS_INLINE Vc_PURE size_t rowsCount() const { return p()->rowsCount(); }
252 };
253 
254 //{{{1
255 /**
256  * \headerfile memorybase.h <Vc/Memory>
257  *
258  * Common interface to all Memory classes, independent of allocation on the stack or heap.
259  *
260  * \param V The vector type you want to operate on. (e.g. float_v or uint_v)
261  * \param Parent This type is the complete type of the class that derives from MemoryBase.
262  * \param Dimension The number of dimensions the implementation provides.
263  * \param RowMemory Class to be used to work on a single row.
264  */
265 template<typename V, typename Parent, int Dimension, typename RowMemory> class MemoryBase : public MemoryDimensionBase<V, Parent, Dimension, RowMemory> //{{{1
266 {
267  private:
268  Parent *p() { return static_cast<Parent *>(this); }
269  const Parent *p() const { return static_cast<const Parent *>(this); }
270  public:
271  /**
272  * The type of the scalar entries in the array.
273  */
274  typedef typename V::EntryType EntryType;
275 
276  /**
277  * \return the number of scalar entries in the array. This function is optimized away
278  * if a constant size array is used.
279  */
280  Vc_ALWAYS_INLINE Vc_PURE size_t entriesCount() const { return p()->entriesCount(); }
281  /**
282  * \return the number of vector entries that span the array. This function is optimized away
283  * if a constant size array is used.
284  */
285  Vc_ALWAYS_INLINE Vc_PURE size_t vectorsCount() const { return p()->vectorsCount(); }
286 
289 
290  /**
291  * \param i Selects the offset, where the vector should be read.
292  *
293  * \return a smart object to wrap the \p i-th vector in the memory.
294  *
295  * The return value can be used as any other vector object. I.e. you can substitute
296  * something like
297  * \code
298  * float_v a = ..., b = ...;
299  * a += b;
300  * \endcode
301  * with
302  * \code
303  * mem.vector(i) += b;
304  * \endcode
305  *
306  * This function ensures that only \em aligned loads and stores are used. Thus it only allows to
307  * access memory at fixed strides. If access to known offsets from the aligned vectors is
308  * needed the vector(size_t, int) function can be used.
309  */
311  return VectorPointerHelper<V, AlignedFlag>(&entries()[i * V::Size]);
312  }
313  /** \brief Const overload of the above function
314  *
315  * \param i Selects the offset, where the vector should be read.
316  *
317  * \return a smart object to wrap the \p i-th vector in the memory.
318  */
320  return VectorPointerHelperConst<V, AlignedFlag>(&entries()[i * V::Size]);
321  }
322 
323  /**
324  * \return a smart object to wrap the vector starting from the \p i-th scalar entry in the memory.
325  *
326  * Example:
327  * \code
328  * Memory<float_v, N> mem;
329  * mem.setZero();
330  * for (int i = 0; i < mem.entriesCount(); i += float_v::Size) {
331  * mem.vectorAt(i) += b;
332  * }
333  * \endcode
334  *
335  * \param i Specifies the scalar entry from where the vector will be loaded/stored. I.e. the
336  * values scalar(i), scalar(i + 1), ..., scalar(i + V::Size - 1) will be read/overwritten.
337  *
338  * \param align You must take care to determine whether an unaligned load/store is
339  * required. Per default an aligned load/store is used. If \p i is not a multiple of \c V::Size
340  * you must pass Vc::Unaligned here.
341  */
342 #ifdef DOXYGEN
343  template<typename A> inline VectorPointerHelper<V, A> vectorAt(size_t i, A align = Vc::Aligned);
344  /** \brief Const overload of the above function
345  *
346  * \return a smart object to wrap the vector starting from the \p i-th scalar entry in the memory.
347  *
348  * \param i Specifies the scalar entry from where the vector will be loaded/stored. I.e. the
349  * values scalar(i), scalar(i + 1), ..., scalar(i + V::Size - 1) will be read/overwritten.
350  *
351  * \param align You must take care to determine whether an unaligned load/store is
352  * required. Per default an aligned load/store is used. If \p i is not a multiple of \c V::Size
353  * you must pass Vc::Unaligned here.
354  */
355  template<typename A> inline const VectorPointerHelperConst<V, A> vectorAt(size_t i, A align = Vc::Aligned) const;
356 #else
357  template<typename A>
359  return VectorPointerHelper<V, A>(&entries()[i]);
360  }
361  template<typename A>
363  return VectorPointerHelperConst<V, A>(&entries()[i]);
364  }
365 
367  return VectorPointerHelper<V, AlignedFlag>(&entries()[i]);
368  }
370  return VectorPointerHelperConst<V, AlignedFlag>(&entries()[i]);
371  }
372 #endif
373 
374  /**
375  * \return a smart object to wrap the \p i-th vector + \p shift in the memory.
376  *
377  * This function ensures that only \em unaligned loads and stores are used.
378  * It allows to access memory at any location aligned to the entry type.
379  *
380  * \param i Selects the memory location of the i-th vector. Thus if \p V::Size == 4 and
381  * \p i is set to 3 the base address for the load/store will be the 12th entry
382  * (same as \p &mem[12]).
383  * \param shift Shifts the base address determined by parameter \p i by \p shift many
384  * entries. Thus \p vector(3, 1) for \p V::Size == 4 will load/store the
385  * 13th - 16th entries (same as \p &mem[13]).
386  *
387  * \note Any shift value is allowed as long as you make sure it stays within bounds of the
388  * allocated memory. Shift values that are a multiple of \p V::Size will \em not result in
389  * aligned loads. You have to use the above vector(size_t) function for aligned loads
390  * instead.
391  *
392  * \note Thus a simple way to access vectors randomly is to set \p i to 0 and use \p shift as the
393  * parameter to select the memory address:
394  * \code
395  * // don't use:
396  * mem.vector(i / V::Size, i % V::Size) += 1;
397  * // instead use:
398  * mem.vector(0, i) += 1;
399  * \endcode
400  */
402  return VectorPointerHelper<V, UnalignedFlag>(&entries()[i * V::Size + shift]);
403  }
404  /// Const overload of the above function.
406  return VectorPointerHelperConst<V, UnalignedFlag>(&entries()[i * V::Size + shift]);
407  }
408 
409  /**
410  * \return the first vector in the allocated memory.
411  *
412  * This function is simply a shorthand for vector(0).
413  */
415  return VectorPointerHelper<V, AlignedFlag>(entries());
416  }
417  /// Const overload of the above function.
420  }
421 
422  /**
423  * \return the last vector in the allocated memory.
424  *
425  * This function is simply a shorthand for vector(vectorsCount() - 1).
426  */
428  return VectorPointerHelper<V, AlignedFlag>(&entries()[vectorsCount() * V::Size - V::Size]);
429  }
430  /// Const overload of the above function.
432  return VectorPointerHelperConst<V, AlignedFlag>(&entries()[vectorsCount() * V::Size - V::Size]);
433  }
434 
435  Vc_ALWAYS_INLINE Vc_PURE V gather(const unsigned char *indexes) const { return V(entries(), indexes); }
436  Vc_ALWAYS_INLINE Vc_PURE V gather(const unsigned short *indexes) const { return V(entries(), indexes); }
437  Vc_ALWAYS_INLINE Vc_PURE V gather(const unsigned int *indexes) const { return V(entries(), indexes); }
438  Vc_ALWAYS_INLINE Vc_PURE V gather(const unsigned long *indexes) const { return V(entries(), indexes); }
439 
441  V zero(Vc::Zero);
442  for (size_t i = 0; i < vectorsCount(); ++i) {
443  vector(i) = zero;
444  }
445  }
446 
447  template<typename P2, typename RM>
448  inline Parent &operator+=(const MemoryBase<V, P2, Dimension, RM> &rhs) {
449  assert(vectorsCount() == rhs.vectorsCount());
450  for (size_t i = 0; i < vectorsCount(); ++i) {
451  vector(i) += rhs.vector(i);
452  }
453  return static_cast<Parent &>(*this);
454  }
455  template<typename P2, typename RM>
456  inline Parent &operator-=(const MemoryBase<V, P2, Dimension, RM> &rhs) {
457  assert(vectorsCount() == rhs.vectorsCount());
458  for (size_t i = 0; i < vectorsCount(); ++i) {
459  vector(i) -= rhs.vector(i);
460  }
461  return static_cast<Parent &>(*this);
462  }
463  template<typename P2, typename RM>
464  inline Parent &operator*=(const MemoryBase<V, P2, Dimension, RM> &rhs) {
465  assert(vectorsCount() == rhs.vectorsCount());
466  for (size_t i = 0; i < vectorsCount(); ++i) {
467  vector(i) *= rhs.vector(i);
468  }
469  return static_cast<Parent &>(*this);
470  }
471  template<typename P2, typename RM>
472  inline Parent &operator/=(const MemoryBase<V, P2, Dimension, RM> &rhs) {
473  assert(vectorsCount() == rhs.vectorsCount());
474  for (size_t i = 0; i < vectorsCount(); ++i) {
475  vector(i) /= rhs.vector(i);
476  }
477  return static_cast<Parent &>(*this);
478  }
479  inline Parent &operator+=(EntryType rhs) {
480  V v(rhs);
481  for (size_t i = 0; i < vectorsCount(); ++i) {
482  vector(i) += v;
483  }
484  return static_cast<Parent &>(*this);
485  }
486  inline Parent &operator-=(EntryType rhs) {
487  V v(rhs);
488  for (size_t i = 0; i < vectorsCount(); ++i) {
489  vector(i) -= v;
490  }
491  return static_cast<Parent &>(*this);
492  }
493  inline Parent &operator*=(EntryType rhs) {
494  V v(rhs);
495  for (size_t i = 0; i < vectorsCount(); ++i) {
496  vector(i) *= v;
497  }
498  return static_cast<Parent &>(*this);
499  }
500  inline Parent &operator/=(EntryType rhs) {
501  V v(rhs);
502  for (size_t i = 0; i < vectorsCount(); ++i) {
503  vector(i) /= v;
504  }
505  return static_cast<Parent &>(*this);
506  }
507  template<typename P2, typename RM>
508  inline bool operator==(const MemoryBase<V, P2, Dimension, RM> &rhs) const {
509  assert(vectorsCount() == rhs.vectorsCount());
510  for (size_t i = 0; i < vectorsCount(); ++i) {
511  if (!(V(vector(i)) == V(rhs.vector(i))).isFull()) {
512  return false;
513  }
514  }
515  return true;
516  }
517  template<typename P2, typename RM>
518  inline bool operator!=(const MemoryBase<V, P2, Dimension, RM> &rhs) const {
519  assert(vectorsCount() == rhs.vectorsCount());
520  for (size_t i = 0; i < vectorsCount(); ++i) {
521  if (!(V(vector(i)) == V(rhs.vector(i))).isEmpty()) {
522  return false;
523  }
524  }
525  return true;
526  }
527  template<typename P2, typename RM>
528  inline bool operator<(const MemoryBase<V, P2, Dimension, RM> &rhs) const {
529  assert(vectorsCount() == rhs.vectorsCount());
530  for (size_t i = 0; i < vectorsCount(); ++i) {
531  if (!(V(vector(i)) < V(rhs.vector(i))).isFull()) {
532  return false;
533  }
534  }
535  return true;
536  }
537  template<typename P2, typename RM>
538  inline bool operator<=(const MemoryBase<V, P2, Dimension, RM> &rhs) const {
539  assert(vectorsCount() == rhs.vectorsCount());
540  for (size_t i = 0; i < vectorsCount(); ++i) {
541  if (!(V(vector(i)) <= V(rhs.vector(i))).isFull()) {
542  return false;
543  }
544  }
545  return true;
546  }
547  template<typename P2, typename RM>
548  inline bool operator>(const MemoryBase<V, P2, Dimension, RM> &rhs) const {
549  assert(vectorsCount() == rhs.vectorsCount());
550  for (size_t i = 0; i < vectorsCount(); ++i) {
551  if (!(V(vector(i)) > V(rhs.vector(i))).isFull()) {
552  return false;
553  }
554  }
555  return true;
556  }
557  template<typename P2, typename RM>
558  inline bool operator>=(const MemoryBase<V, P2, Dimension, RM> &rhs) const {
559  assert(vectorsCount() == rhs.vectorsCount());
560  for (size_t i = 0; i < vectorsCount(); ++i) {
561  if (!(V(vector(i)) >= V(rhs.vector(i))).isFull()) {
562  return false;
563  }
564  }
565  return true;
566  }
567 };
568 
569 namespace Internal
570 {
571 template <typename V,
572  typename ParentL,
573  typename ParentR,
574  int Dimension,
575  typename RowMemoryL,
576  typename RowMemoryR>
579 {
580  const size_t vectorsCount = dst.vectorsCount();
581  size_t i = 3;
582  for (; i < vectorsCount; i += 4) {
583  const V tmp3 = src.vector(i - 3);
584  const V tmp2 = src.vector(i - 2);
585  const V tmp1 = src.vector(i - 1);
586  const V tmp0 = src.vector(i - 0);
587  dst.vector(i - 3) = tmp3;
588  dst.vector(i - 2) = tmp2;
589  dst.vector(i - 1) = tmp1;
590  dst.vector(i - 0) = tmp0;
591  }
592  for (i -= 3; i < vectorsCount; ++i) {
593  dst.vector(i) = src.vector(i);
594  }
595 }
596 } // namespace Internal
597 
598 } // namespace Vc
599 } // namespace ROOT
600 
601 #include "undomacros.h"
602 
603 #endif // VC_COMMON_MEMORYBASE_H
Parent & operator-=(const MemoryBase< V, P2, Dimension, RM > &rhs)
Definition: memorybase.h:456
one y
Definition: memorybase.h:38
Helper class for the Memory::vector(size_t) class of functions.
Definition: memorybase.h:83
Vc_ALWAYS_INLINE Vc_PURE const VectorPointerHelperConst< V, UnalignedFlag > vector(size_t i, int shift) const
Const overload of the above function.
Definition: memorybase.h:405
#define VC_VPH_OPERATOR(op)
Definition: memorybase.h:137
Namespace for new ROOT classes and functions.
Definition: ROOT.py:1
Vc_ALWAYS_INLINE Vc_PURE const EntryType scalar(size_t i) const
Const overload of the above function.
Definition: memorybase.h:171
Vc_ALWAYS_INLINE Vc_PURE VectorPointerHelper< V, UnalignedFlag > vector(size_t i, int shift)
Definition: memorybase.h:401
#define VC_ALL_ARITHMETICS(macro)
Definition: macros.h:358
Vc_ALWAYS_INLINE Vc_PURE const VectorPointerHelperConst< V, AlignedFlag > lastVector() const
Const overload of the above function.
Definition: memorybase.h:431
bool operator>(const MemoryBase< V, P2, Dimension, RM > &rhs) const
Definition: memorybase.h:548
const char * Size
Definition: TXMLSetup.cxx:56
double T(double x)
Definition: ChebyshevPol.h:34
#define assert(cond)
Definition: unittest.h:542
Vc_ALWAYS_INLINE Vc_PURE EntryType & scalar(size_t i, size_t j)
Returns the i,j-th scalar value in the memory.
Definition: memorybase.h:231
Vc_ALWAYS_INLINE Vc_PURE V gather(const unsigned short *indexes) const
Definition: memorybase.h:436
Vc_ALWAYS_INLINE Vc_PURE const VectorPointerHelperConst< V, A > vectorAt(size_t i, A) const
Definition: memorybase.h:362
#define VC_ALL_BINARY(macro)
Definition: macros.h:356
Parent & operator/=(EntryType rhs)
Definition: memorybase.h:500
bool operator==(const MemoryBase< V, P2, Dimension, RM > &rhs) const
Definition: memorybase.h:508
Vc_ALWAYS_INLINE Vc_PURE VectorPointerHelper< V, AlignedFlag > vectorAt(size_t i)
Definition: memorybase.h:366
static double A[]
bool operator!=(const MemoryBase< V, P2, Dimension, RM > &rhs) const
Definition: memorybase.h:518
VectorPointerHelper(EntryType *ptr)
Definition: memorybase.h:115
Parent & operator+=(EntryType rhs)
Definition: memorybase.h:479
Vc_ALWAYS_INLINE Vc_PURE V gather(const unsigned int *indexes) const
Definition: memorybase.h:437
Vc_ALWAYS_INLINE Vc_PURE size_t vectorsCount() const
Definition: memorybase.h:285
Parent & operator*=(EntryType rhs)
Definition: memorybase.h:493
Vc_ALWAYS_INLINE Vc_PURE EntryType * entries()
Returns a pointer to the start of the allocated memory.
Definition: memorybase.h:162
char x
Definition: memorybase.h:37
Vc_ALWAYS_INLINE Vc_PURE VectorPointerHelper< V, AlignedFlag > vector(size_t i)
Definition: memorybase.h:310
Parent & operator*=(const MemoryBase< V, P2, Dimension, RM > &rhs)
Definition: memorybase.h:464
Parent & operator+=(const MemoryBase< V, P2, Dimension, RM > &rhs)
Definition: memorybase.h:448
Vc_ALWAYS_INLINE Vc_PURE size_t entriesCount() const
Definition: memorybase.h:280
Vc_ALWAYS_INLINE VectorPointerHelper & operator=(const T &x)
Definition: memorybase.h:125
#define Vc_PURE
Definition: macros.h:136
Vc_ALWAYS_INLINE Vc_PURE const EntryType * entries() const
Const overload of the above function.
Definition: memorybase.h:164
bool operator>=(const MemoryBase< V, P2, Dimension, RM > &rhs) const
Definition: memorybase.h:558
SVector< double, 2 > v
Definition: Dict.h:5
Vc_ALWAYS_INLINE Vc_PURE EntryType * entries(size_t x=0)
Returns a pointer to the start of the allocated memory.
Definition: memorybase.h:224
Vc_ALWAYS_INLINE Vc_PURE V gather(const unsigned long *indexes) const
Definition: memorybase.h:438
VectorPointerHelperConst(const EntryType *ptr)
Definition: memorybase.h:90
Vc_ALWAYS_INLINE Vc_PURE const VectorPointerHelperConst< V, AlignedFlag > firstVector() const
Const overload of the above function.
Definition: memorybase.h:418
Vc_ALWAYS_INLINE Vc_PURE const EntryType * entries(size_t x=0) const
Const overload of the above function.
Definition: memorybase.h:226
#define VC_ALL_COMPARES(macro)
Definition: macros.h:354
Helper class for the Memory::vector(size_t) class of functions.
Definition: memorybase.h:108
Vc_ALWAYS_INLINE Vc_PURE const EntryType scalar(size_t i, size_t j) const
Const overload of the above function.
Definition: memorybase.h:233
Vc_ALWAYS_INLINE Vc_PURE const RowMemory & operator[](size_t i) const
Const overload of the above function.
Definition: memorybase.h:242
#define Vc_ALWAYS_INLINE
Definition: macros.h:130
Parent & operator/=(const MemoryBase< V, P2, Dimension, RM > &rhs)
Definition: memorybase.h:472
V::EntryType EntryType
The type of the scalar entries in the array.
Definition: memorybase.h:274
Vc_ALWAYS_INLINE Vc_PURE const VectorPointerHelperConst< V, AlignedFlag > vectorAt(size_t i) const
Definition: memorybase.h:369
V::EntryType EntryType
The type of the scalar entries in the array.
Definition: memorybase.h:157
#define T2
Definition: md5.inl:146
Vc_ALWAYS_INLINE Vc_PURE V gather(const unsigned char *indexes) const
Definition: memorybase.h:435
Parent & operator-=(EntryType rhs)
Definition: memorybase.h:486
Vc_ALWAYS_INLINE Vc_PURE const VectorPointerHelperConst< V, AlignedFlag > vector(size_t i) const
Const overload of the above function.
Definition: memorybase.h:319
Vc_ALWAYS_INLINE Vc_PURE VectorPointerHelper< V, AlignedFlag > firstVector()
Definition: memorybase.h:414
const Parent * p() const
Definition: memorybase.h:269
#define _VC_CONSTEXPR
Definition: macros.h:154
#define T1
Definition: md5.inl:145
Vc_ALWAYS_INLINE Vc_PURE EntryType & scalar(size_t i)
Returns the i-th scalar value in the memory.
Definition: memorybase.h:169
Common interface to all Memory classes, independent of allocation on the stack or heap...
Definition: memorybase.h:265
Vc_ALWAYS_INLINE Vc_PURE RowMemory & operator[](size_t i)
Returns the i-th row in the memory.
Definition: memorybase.h:238
Definition: casts.h:28
const EntryType *const m_ptr
Definition: memorybase.h:88
#define VC_MEM_OPERATOR_EQ(op)
Definition: memorybase.h:67
V::EntryType EntryType
The type of the scalar entries in the array.
Definition: memorybase.h:217
Vc_ALWAYS_INLINE Vc_PURE V operator[](Vector< IndexT > i) const
Uses a vector gather to combine the entries at the indexes in i into the returned vector object...
Definition: memorybase.h:203
Vc_ALWAYS_INLINE void setZero()
Definition: memorybase.h:440
Vc_ALWAYS_INLINE Vc_PURE VectorPointerHelper< V, AlignedFlag > lastVector()
Definition: memorybase.h:427
Vc_ALWAYS_INLINE Vc_PURE size_t rowsCount() const
Definition: memorybase.h:251
Vc_ALWAYS_INLINE Vc_PURE VectorPointerHelper< V, A > vectorAt(size_t i, A)
Definition: memorybase.h:358
void copyVectors(MemoryBase< V, ParentL, Dimension, RowMemoryL > &dst, const MemoryBase< V, ParentR, Dimension, RowMemoryR > &src)
Definition: memorybase.h:577
const char * Value
Definition: TXMLSetup.cxx:73