28 #ifndef VC_COMMON_ELEMENTREFERENCE_H_
29 #define VC_COMMON_ELEMENTREFERENCE_H_
33 namespace Vc_VERSIONED_NAMESPACE
37 template <
typename U,
typename Accessor = U>
class ElementReference
39 using value_type =
typename U::value_type;
42 Vc_INTRINSIC ElementReference(U &o,
int i) noexcept : index(i), obj(o) {}
44 static constexpr
bool get_noexcept =
45 noexcept(Accessor::get(std::declval<U &>(),
int()));
46 template <
typename T>
static constexpr
bool set_noexcept()
48 return noexcept(Accessor::set(std::declval<U &>(),
int(), std::declval<T>()));
52 Vc_INTRINSIC ElementReference(
const ElementReference &) =
delete;
71 Vc_INTRINSIC ElementReference(ElementReference &&) =
default;
73 Vc_INTRINSIC
operator value_type() const noexcept(get_noexcept)
75 return Accessor::get(obj, index);
79 Vc_INTRINSIC ElementReference &operator=(T &&x) &&
80 noexcept(noexcept(Accessor::set(std::declval<U &>(),
int(), std::declval<T>())))
82 Accessor::set(obj, index, std::forward<T>(x));
89 template <typename T, typename R = decltype(std::declval<const value_type &>() \
90 op_ std::declval<T>())> \
91 Vc_INTRINSIC ElementReference &operator op_##=(T &&x) && \
92 noexcept(get_noexcept && noexcept(Accessor::set(std::declval<U &>(), int(), \
93 std::declval<R &&>()))) \
95 const value_type &lhs = Accessor::get(obj, index); \
96 Accessor::set(obj, index, lhs op_ std::forward<T>(x)); \
99 Vc_ALL_ARITHMETICS(Vc_OP_);
100 Vc_ALL_SHIFTS(Vc_OP_);
101 Vc_ALL_BINARY(Vc_OP_);
104 template <
typename =
void>
105 Vc_INTRINSIC ElementReference &operator++() &&
106 noexcept(noexcept(std::declval<value_type &>() =
107 Accessor::get(std::declval<U &>(),
int())) &&
108 set_noexcept<decltype(++std::declval<value_type &>())>())
110 value_type x = Accessor::get(obj, index);
111 Accessor::set(obj, index, ++x);
115 template <
typename =
void>
116 Vc_INTRINSIC value_type operator++(
int) &&
117 noexcept(noexcept(std::declval<value_type &>() =
118 Accessor::get(std::declval<U &>(),
int())) &&
119 set_noexcept<decltype(std::declval<value_type &>()++)>())
121 const value_type r = Accessor::get(obj, index);
123 Accessor::set(obj, index, ++x);
127 template <
typename =
void>
128 Vc_INTRINSIC ElementReference &operator--() &&
129 noexcept(noexcept(std::declval<value_type &>() =
130 Accessor::get(std::declval<U &>(),
int())) &&
131 set_noexcept<decltype(--std::declval<value_type &>())>())
133 value_type x = Accessor::get(obj, index);
134 Accessor::set(obj, index, --x);
138 template <
typename =
void>
139 Vc_INTRINSIC value_type operator--(
int) &&
140 noexcept(noexcept(std::declval<value_type &>() =
141 Accessor::get(std::declval<U &>(),
int())) &&
142 set_noexcept<decltype(std::declval<value_type &>()--)>())
144 const value_type r = Accessor::get(obj, index);
146 Accessor::set(obj, index, --x);
150 friend void swap(ElementReference &&a, ElementReference &&b) {
152 static_cast<ElementReference &&
>(a) = static_cast<value_type>(b);
153 static_cast<ElementReference &&
>(b) = tmp;
156 friend void swap(value_type &a, ElementReference &&b) {
158 a =
static_cast<value_type
>(b);
159 static_cast<ElementReference &&
>(b) = tmp;
162 friend void swap(ElementReference &&a, value_type &b) {
164 static_cast<ElementReference &&
>(a) = b;
176 #endif // VC_COMMON_ELEMENTREFERENCE_H_
void swap(Adapter< S, T, N > &a, std::size_t i, S &x)
Swaps one scalar object x with a SIMD slot at offset i in the simdized object a.