File indexing completed on 2025-01-30 10:25:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifndef VC_COMMON_ELEMENTREFERENCE_H_
0029 #define VC_COMMON_ELEMENTREFERENCE_H_
0030
0031 #include "macros.h"
0032
0033 namespace Vc_VERSIONED_NAMESPACE
0034 {
0035 namespace Detail
0036 {
0037 template <typename U, typename Accessor = U> class ElementReference
0038 {
0039 friend U;
0040 friend Accessor;
0041 Vc_INTRINSIC ElementReference(U &o, int i) noexcept : index(i), obj(o) {}
0042
0043 static constexpr bool get_noexcept =
0044 noexcept(Accessor::get(std::declval<U &>(), int()));
0045 template <typename T> static constexpr bool set_noexcept()
0046 {
0047 return noexcept(Accessor::set(std::declval<U &>(), int(), std::declval<T>()));
0048 }
0049
0050 public:
0051 using value_type = typename U::value_type;
0052 Vc_INTRINSIC ElementReference(const ElementReference &) = delete;
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 Vc_INTRINSIC ElementReference(ElementReference &&) = default;
0072
0073 Vc_INTRINSIC operator value_type() const noexcept(get_noexcept)
0074 {
0075 return Accessor::get(obj, index);
0076 }
0077
0078 template <typename T>
0079 Vc_INTRINSIC ElementReference &operator=(T &&x) &&
0080 noexcept(noexcept(Accessor::set(std::declval<U &>(), int(), std::declval<T>())))
0081 {
0082 Accessor::set(obj, index, std::forward<T>(x));
0083 return *this;
0084 }
0085
0086
0087
0088 #define Vc_OP_(op_) \
0089 template <typename T, typename R = decltype(std::declval<const value_type &>() \
0090 op_ std::declval<T>())> \
0091 Vc_INTRINSIC ElementReference &operator op_##=(T &&x) && \
0092 noexcept(get_noexcept && noexcept(Accessor::set(std::declval<U &>(), int(), \
0093 std::declval<R &&>()))) \
0094 { \
0095 const value_type &lhs = Accessor::get(obj, index); \
0096 Accessor::set(obj, index, lhs op_ std::forward<T>(x)); \
0097 return *this; \
0098 }
0099 Vc_ALL_ARITHMETICS(Vc_OP_);
0100 Vc_ALL_SHIFTS(Vc_OP_);
0101 Vc_ALL_BINARY(Vc_OP_);
0102 #undef Vc_OP_
0103
0104 template <typename = void>
0105 Vc_INTRINSIC ElementReference &operator++() &&
0106 noexcept(noexcept(std::declval<value_type &>() =
0107 Accessor::get(std::declval<U &>(), int())) &&
0108 set_noexcept<decltype(++std::declval<value_type &>())>())
0109 {
0110 value_type x = Accessor::get(obj, index);
0111 Accessor::set(obj, index, ++x);
0112 return *this;
0113 }
0114
0115 template <typename = void>
0116 Vc_INTRINSIC value_type operator++(int) &&
0117 noexcept(noexcept(std::declval<value_type &>() =
0118 Accessor::get(std::declval<U &>(), int())) &&
0119 set_noexcept<decltype(std::declval<value_type &>()++)>())
0120 {
0121 const value_type r = Accessor::get(obj, index);
0122 value_type x = r;
0123 Accessor::set(obj, index, ++x);
0124 return r;
0125 }
0126
0127 template <typename = void>
0128 Vc_INTRINSIC ElementReference &operator--() &&
0129 noexcept(noexcept(std::declval<value_type &>() =
0130 Accessor::get(std::declval<U &>(), int())) &&
0131 set_noexcept<decltype(--std::declval<value_type &>())>())
0132 {
0133 value_type x = Accessor::get(obj, index);
0134 Accessor::set(obj, index, --x);
0135 return *this;
0136 }
0137
0138 template <typename = void>
0139 Vc_INTRINSIC value_type operator--(int) &&
0140 noexcept(noexcept(std::declval<value_type &>() =
0141 Accessor::get(std::declval<U &>(), int())) &&
0142 set_noexcept<decltype(std::declval<value_type &>()--)>())
0143 {
0144 const value_type r = Accessor::get(obj, index);
0145 value_type x = r;
0146 Accessor::set(obj, index, --x);
0147 return r;
0148 }
0149
0150 friend void swap(ElementReference &&a, ElementReference &&b) {
0151 value_type tmp(a);
0152 static_cast<ElementReference &&>(a) = static_cast<value_type>(b);
0153 static_cast<ElementReference &&>(b) = tmp;
0154 }
0155
0156 friend void swap(value_type &a, ElementReference &&b) {
0157 value_type tmp(a);
0158 a = static_cast<value_type>(b);
0159 static_cast<ElementReference &&>(b) = tmp;
0160 }
0161
0162 friend void swap(ElementReference &&a, value_type &b) {
0163 value_type tmp(a);
0164 static_cast<ElementReference &&>(a) = b;
0165 b = tmp;
0166 }
0167
0168 private:
0169 int index;
0170 U &obj;
0171 };
0172
0173 }
0174 }
0175
0176 #endif
0177
0178