20 #ifndef VC_COMMON_MEMORYBASE_H
21 #define VC_COMMON_MEMORYBASE_H
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
37 struct one {
char x; };
38 struct two { one
x,
y; };
39 template<
typename T1,
typename T2>
struct DecltypeHelper
41 static one test(
const T1 &) {
return one(); }
42 static two test(
const T2 &) {
return two(); }
45 template<
typename T1>
struct DecltypeHelper<
T1,
T1>
47 static one test(
const T1 &) {
return one(); }
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; };
59 #define VC_DECLTYPE(T1, op, T2) typename Decltype<T1, T2, sizeof(DecltypeHelper<T1, T2>::test(T1() op T2()))>::Value
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
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()); \
86 typedef typename V::Mask
Mask;
135 #undef VC_MEM_OPERATOR_EQ
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()); \
145 #undef VC_VPH_OPERATOR
148 template<
typename V,
typename Parent,
typename RowMemory>
class MemoryDimensionBase<V, Parent, 1, RowMemory>
151 Parent *
p() {
return static_cast<Parent *
>(
this); }
152 const Parent *
p()
const {
return static_cast<const Parent *
>(
this); }
189 inline const EntryType &operator[](
size_t i)
const;
205 return V(entries(), i);
208 template<
typename V,
typename Parent,
typename RowMemory>
class MemoryDimensionBase<V, Parent, 2, RowMemory>
211 Parent *
p() {
return static_cast<Parent *
>(
this); }
212 const Parent *
p()
const {
return static_cast<const Parent *
>(
this); }
239 return RowMemory::fromRawData(entries(i));
243 return RowMemory::fromRawData(const_cast<EntryType *>(entries(i)));
268 Parent *
p() {
return static_cast<Parent *
>(
this); }
269 const Parent *
p()
const {
return static_cast<const Parent *
>(
this); }
442 for (
size_t i = 0; i < vectorsCount(); ++i) {
447 template<
typename P2,
typename RM>
450 for (
size_t i = 0; i < vectorsCount(); ++i) {
451 vector(i) += rhs.
vector(i);
453 return static_cast<Parent &
>(*this);
455 template<
typename P2,
typename RM>
458 for (
size_t i = 0; i < vectorsCount(); ++i) {
459 vector(i) -= rhs.
vector(i);
461 return static_cast<Parent &
>(*this);
463 template<
typename P2,
typename RM>
466 for (
size_t i = 0; i < vectorsCount(); ++i) {
467 vector(i) *= rhs.
vector(i);
469 return static_cast<Parent &
>(*this);
471 template<
typename P2,
typename RM>
474 for (
size_t i = 0; i < vectorsCount(); ++i) {
475 vector(i) /= rhs.
vector(i);
477 return static_cast<Parent &
>(*this);
481 for (
size_t i = 0; i < vectorsCount(); ++i) {
484 return static_cast<Parent &
>(*this);
488 for (
size_t i = 0; i < vectorsCount(); ++i) {
491 return static_cast<Parent &
>(*this);
495 for (
size_t i = 0; i < vectorsCount(); ++i) {
498 return static_cast<Parent &
>(*this);
502 for (
size_t i = 0; i < vectorsCount(); ++i) {
505 return static_cast<Parent &
>(*this);
507 template<
typename P2,
typename RM>
510 for (
size_t i = 0; i < vectorsCount(); ++i) {
511 if (!(V(vector(i)) == V(rhs.
vector(i))).isFull()) {
517 template<
typename P2,
typename RM>
520 for (
size_t i = 0; i < vectorsCount(); ++i) {
521 if (!(V(vector(i)) == V(rhs.
vector(i))).isEmpty()) {
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()) {
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()) {
547 template<
typename P2,
typename RM>
550 for (
size_t i = 0; i < vectorsCount(); ++i) {
551 if (!(V(vector(i)) > V(rhs.
vector(i))).isFull()) {
557 template<
typename P2,
typename RM>
560 for (
size_t i = 0; i < vectorsCount(); ++i) {
561 if (!(V(vector(i)) >= V(rhs.
vector(i))).isFull()) {
571 template <
typename V,
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);
592 for (i -= 3; i < vectorsCount; ++i) {
603 #endif // VC_COMMON_MEMORYBASE_H
Parent & operator-=(const MemoryBase< V, P2, Dimension, RM > &rhs)
Helper class for the Memory::vector(size_t) class of functions.
Vc_ALWAYS_INLINE Vc_PURE const VectorPointerHelperConst< V, UnalignedFlag > vector(size_t i, int shift) const
Const overload of the above function.
#define VC_VPH_OPERATOR(op)
Vc_ALWAYS_INLINE Vc_PURE const EntryType scalar(size_t i) const
Const overload of the above function.
Vc_ALWAYS_INLINE Vc_PURE VectorPointerHelper< V, UnalignedFlag > vector(size_t i, int shift)
#define VC_ALL_ARITHMETICS(macro)
Vc_ALWAYS_INLINE Vc_PURE const VectorPointerHelperConst< V, AlignedFlag > lastVector() const
Const overload of the above function.
bool operator>(const MemoryBase< V, P2, Dimension, RM > &rhs) const
Vc_ALWAYS_INLINE Vc_PURE EntryType & scalar(size_t i, size_t j)
Returns the i,j-th scalar value in the memory.
Vc_ALWAYS_INLINE Vc_PURE V gather(const unsigned short *indexes) const
Vc_ALWAYS_INLINE Vc_PURE const VectorPointerHelperConst< V, A > vectorAt(size_t i, A) const
#define VC_ALL_BINARY(macro)
Parent & operator/=(EntryType rhs)
bool operator==(const MemoryBase< V, P2, Dimension, RM > &rhs) const
Vc_ALWAYS_INLINE Vc_PURE VectorPointerHelper< V, AlignedFlag > vectorAt(size_t i)
bool operator!=(const MemoryBase< V, P2, Dimension, RM > &rhs) const
VectorPointerHelper(EntryType *ptr)
Parent & operator+=(EntryType rhs)
Vc_ALWAYS_INLINE Vc_PURE V gather(const unsigned int *indexes) const
Vc_ALWAYS_INLINE Vc_PURE size_t vectorsCount() const
Parent & operator*=(EntryType rhs)
Vc_ALWAYS_INLINE Vc_PURE EntryType * entries()
Returns a pointer to the start of the allocated memory.
Vc_ALWAYS_INLINE Vc_PURE VectorPointerHelper< V, AlignedFlag > vector(size_t i)
Parent & operator*=(const MemoryBase< V, P2, Dimension, RM > &rhs)
Parent & operator+=(const MemoryBase< V, P2, Dimension, RM > &rhs)
Vc_ALWAYS_INLINE Vc_PURE size_t entriesCount() const
Vc_ALWAYS_INLINE VectorPointerHelper & operator=(const T &x)
Vc_ALWAYS_INLINE Vc_PURE const EntryType * entries() const
Const overload of the above function.
bool operator>=(const MemoryBase< V, P2, Dimension, RM > &rhs) const
Vc_ALWAYS_INLINE Vc_PURE EntryType * entries(size_t x=0)
Returns a pointer to the start of the allocated memory.
Vc_ALWAYS_INLINE Vc_PURE V gather(const unsigned long *indexes) const
VectorPointerHelperConst(const EntryType *ptr)
Vc_ALWAYS_INLINE Vc_PURE const VectorPointerHelperConst< V, AlignedFlag > firstVector() const
Const overload of the above function.
Vc_ALWAYS_INLINE Vc_PURE const EntryType * entries(size_t x=0) const
Const overload of the above function.
#define VC_ALL_COMPARES(macro)
Helper class for the Memory::vector(size_t) class of functions.
Vc_ALWAYS_INLINE Vc_PURE const EntryType scalar(size_t i, size_t j) const
Const overload of the above function.
Vc_ALWAYS_INLINE Vc_PURE const RowMemory & operator[](size_t i) const
Const overload of the above function.
static _VC_CONSTEXPR size_t rowCount()
Parent & operator/=(const MemoryBase< V, P2, Dimension, RM > &rhs)
V::EntryType EntryType
The type of the scalar entries in the array.
Vc_ALWAYS_INLINE Vc_PURE const VectorPointerHelperConst< V, AlignedFlag > vectorAt(size_t i) const
V::EntryType EntryType
The type of the scalar entries in the array.
Vc_ALWAYS_INLINE Vc_PURE V gather(const unsigned char *indexes) const
Parent & operator-=(EntryType rhs)
Vc_ALWAYS_INLINE Vc_PURE const VectorPointerHelperConst< V, AlignedFlag > vector(size_t i) const
Const overload of the above function.
Vc_ALWAYS_INLINE Vc_PURE VectorPointerHelper< V, AlignedFlag > firstVector()
Vc_ALWAYS_INLINE Vc_PURE EntryType & scalar(size_t i)
Returns the i-th scalar value in the memory.
Common interface to all Memory classes, independent of allocation on the stack or heap...
Vc_ALWAYS_INLINE Vc_PURE RowMemory & operator[](size_t i)
Returns the i-th row in the memory.
const EntryType *const m_ptr
#define VC_MEM_OPERATOR_EQ(op)
V::EntryType EntryType
The type of the scalar entries in the array.
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...
Vc_ALWAYS_INLINE void setZero()
Vc_ALWAYS_INLINE Vc_PURE VectorPointerHelper< V, AlignedFlag > lastVector()
Vc_ALWAYS_INLINE Vc_PURE size_t rowsCount() const
Vc_ALWAYS_INLINE Vc_PURE VectorPointerHelper< V, A > vectorAt(size_t i, A)
void copyVectors(MemoryBase< V, ParentL, Dimension, RowMemoryL > &dst, const MemoryBase< V, ParentR, Dimension, RowMemoryR > &src)