29 #ifndef VC_COMMON_WHERE_H_
30 #define VC_COMMON_WHERE_H_
35 namespace Vc_VERSIONED_NAMESPACE
45 template<
typename _Mask,
typename _LValue>
struct MaskedLValue
48 typedef _LValue LValue;
54 constexpr MaskedLValue(
const Mask &m, LValue &l) : mask(m), lhs(l) {}
55 MaskedLValue(
const MaskedLValue &) =
delete;
56 constexpr MaskedLValue(MaskedLValue &&) =
default;
62 template<
typename T> Vc_ALWAYS_INLINE
void operator =(T &&rhs) { conditional_assign<Operator:: Assign>(lhs, mask, std::forward<T>(rhs)); }
63 template<
typename T> Vc_ALWAYS_INLINE
void operator +=(T &&rhs) { conditional_assign<Operator:: PlusAssign>(lhs, mask, std::forward<T>(rhs)); }
64 template<
typename T> Vc_ALWAYS_INLINE
void operator -=(T &&rhs) { conditional_assign<Operator:: MinusAssign>(lhs, mask, std::forward<T>(rhs)); }
65 template<
typename T> Vc_ALWAYS_INLINE
void operator *=(T &&rhs) { conditional_assign<Operator:: MultiplyAssign>(lhs, mask, std::forward<T>(rhs)); }
66 template<
typename T> Vc_ALWAYS_INLINE
void operator /=(T &&rhs) { conditional_assign<Operator:: DivideAssign>(lhs, mask, std::forward<T>(rhs)); }
67 template<
typename T> Vc_ALWAYS_INLINE
void operator %=(T &&rhs) { conditional_assign<Operator:: RemainderAssign>(lhs, mask, std::forward<T>(rhs)); }
68 template<
typename T> Vc_ALWAYS_INLINE
void operator ^=(T &&rhs) { conditional_assign<Operator:: XorAssign>(lhs, mask, std::forward<T>(rhs)); }
69 template<
typename T> Vc_ALWAYS_INLINE
void operator &=(T &&rhs) { conditional_assign<Operator:: AndAssign>(lhs, mask, std::forward<T>(rhs)); }
70 template<
typename T> Vc_ALWAYS_INLINE
void operator |=(T &&rhs) { conditional_assign<Operator:: OrAssign>(lhs, mask, std::forward<T>(rhs)); }
71 template<
typename T> Vc_ALWAYS_INLINE
void operator<<=(T &&rhs) { conditional_assign<Operator:: LeftShiftAssign>(lhs, mask, std::forward<T>(rhs)); }
72 template<
typename T> Vc_ALWAYS_INLINE
void operator>>=(T &&rhs) { conditional_assign<Operator::RightShiftAssign>(lhs, mask, std::forward<T>(rhs)); }
73 Vc_ALWAYS_INLINE
void operator++() { conditional_assign<Operator:: PreIncrement>(lhs, mask); }
74 Vc_ALWAYS_INLINE
void operator++(
int) { conditional_assign<Operator::PostIncrement>(lhs, mask); }
75 Vc_ALWAYS_INLINE
void operator--() { conditional_assign<Operator:: PreDecrement>(lhs, mask); }
76 Vc_ALWAYS_INLINE
void operator--(
int) { conditional_assign<Operator::PostDecrement>(lhs, mask); }
79 template <
typename _Mask,
typename T_,
typename I_,
typename S_>
80 struct MaskedLValue<_Mask, Common::SubscriptOperation<T_, I_, S_, true>>
83 typedef Common::SubscriptOperation<T_, I_, S_, true> SO;
88 template <
typename T>
using Decay =
typename std::decay<T>::type;
91 constexpr MaskedLValue(
const Mask &m, SO &&l) : mask(m), lhs(l) {}
92 MaskedLValue(
const MaskedLValue &) =
delete;
93 constexpr MaskedLValue(MaskedLValue &&) =
default;
99 template<
typename T> Vc_ALWAYS_INLINE
void operator =(T &&rhs) { std::forward<T>(rhs).scatter(lhs.scatterArguments(), mask); }
124 template<
typename _LValue>
struct MaskedLValue<bool, _LValue>
127 typedef _LValue LValue;
133 constexpr MaskedLValue(
const Mask &m, LValue &l) : mask(m), lhs(l) {}
134 MaskedLValue(
const MaskedLValue &) =
delete;
135 constexpr MaskedLValue(MaskedLValue &&) =
default;
137 template<
typename T> Vc_ALWAYS_INLINE
void operator =(T &&rhs) {
if (mask) lhs = std::forward<T>(rhs); }
138 template<
typename T> Vc_ALWAYS_INLINE
void operator +=(T &&rhs) {
if (mask) lhs += std::forward<T>(rhs); }
139 template<
typename T> Vc_ALWAYS_INLINE
void operator -=(T &&rhs) {
if (mask) lhs -= std::forward<T>(rhs); }
140 template<
typename T> Vc_ALWAYS_INLINE
void operator *=(T &&rhs) {
if (mask) lhs *= std::forward<T>(rhs); }
141 template<
typename T> Vc_ALWAYS_INLINE
void operator /=(T &&rhs) {
if (mask) lhs /= std::forward<T>(rhs); }
142 template<
typename T> Vc_ALWAYS_INLINE
void operator %=(T &&rhs) {
if (mask) lhs %= std::forward<T>(rhs); }
143 template<
typename T> Vc_ALWAYS_INLINE
void operator ^=(T &&rhs) {
if (mask) lhs ^= std::forward<T>(rhs); }
144 template<
typename T> Vc_ALWAYS_INLINE
void operator &=(T &&rhs) {
if (mask) lhs &= std::forward<T>(rhs); }
145 template<
typename T> Vc_ALWAYS_INLINE
void operator |=(T &&rhs) {
if (mask) lhs |= std::forward<T>(rhs); }
146 template<
typename T> Vc_ALWAYS_INLINE
void operator<<=(T &&rhs) {
if (mask) lhs <<= std::forward<T>(rhs); }
147 template<
typename T> Vc_ALWAYS_INLINE
void operator>>=(T &&rhs) {
if (mask) lhs >>= std::forward<T>(rhs); }
148 Vc_ALWAYS_INLINE
void operator++() {
if (mask) ++lhs; }
149 Vc_ALWAYS_INLINE
void operator++(
int) {
if (mask) lhs++; }
150 Vc_ALWAYS_INLINE
void operator--() {
if (mask) --lhs; }
151 Vc_ALWAYS_INLINE
void operator--(
int) {
if (mask) lhs--; }
154 template<
typename _Mask>
struct WhereMask
160 constexpr WhereMask(
const Mask &m) : mask(m) {}
161 WhereMask(
const WhereMask &) =
delete;
163 template <
typename T,
typename I,
typename S>
164 constexpr Vc_WARN_UNUSED_RESULT
165 MaskedLValue<Mask, Common::SubscriptOperation<T, I, S, true>>
166 operator|(Common::SubscriptOperation<T, I, S, true> &&lhs)
const
168 static_assert(!std::is_const<T>::value,
169 "masked scatter to constant memory not possible.");
170 return {mask, std::move(lhs)};
173 template<
typename T> constexpr Vc_WARN_UNUSED_RESULT MaskedLValue<Mask, T> operator|(T &&lhs)
const
175 static_assert(std::is_lvalue_reference<T>::value,
"Syntax error: Incorrect use of Vc::where. Maybe operator precedence got you by surprise. Examples of correct usage:\n"
176 " Vc::where(x < 2) | x += 1;\n"
177 " (Vc::where(x < 2) | x)++;\n"
178 " Vc::where(x < 2)(x) += 1;\n"
179 " Vc::where(x < 2)(x)++;\n"
181 return { mask, lhs };
184 template<
typename T> constexpr Vc_WARN_UNUSED_RESULT MaskedLValue<Mask, T> operator()(T &&lhs)
const
186 return operator|(std::forward<T>(lhs));
230 template<
typename M> constexpr Vc_WARN_UNUSED_RESULT WhereImpl::WhereMask<M>
where(
const M &mask)
235 template<
typename M> constexpr Vc_WARN_UNUSED_RESULT WhereImpl::WhereMask<M> _if(
const M &m)
242 #endif // VC_COMMON_WHERE_H_
constexpr WhereImpl::WhereMask< M > where(const M &mask)
Conditional assignment.