1 /*************************************************************************** 2 * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht * 3 * Copyright (c) QuantStack * 4 * * 5 * Distributed under the terms of the BSD 3-Clause License. * 6 * * 7 * The full license is in the file LICENSE, distributed with this software. * 8 ****************************************************************************/ 9 10 #ifndef XTENSOR_NOALIAS_HPP 11 #define XTENSOR_NOALIAS_HPP 12 13 #include "xsemantic.hpp" 14 15 namespace xt 16 { 17 18 template <class A> 19 class noalias_proxy 20 { 21 22 public: 23 24 noalias_proxy(A a) noexcept; 25 26 template <class E> 27 disable_xexpression<E, A> operator=(const E&); 28 29 template <class E> 30 disable_xexpression<E, A> operator+=(const E&); 31 32 template <class E> 33 disable_xexpression<E, A> operator-=(const E&); 34 35 template <class E> 36 disable_xexpression<E, A> operator*=(const E&); 37 38 template <class E> 39 disable_xexpression<E, A> operator/=(const E&); 40 41 template <class E> 42 disable_xexpression<E, A> operator%=(const E&); 43 44 template <class E> 45 disable_xexpression<E, A> operator&=(const E&); 46 47 template <class E> 48 disable_xexpression<E, A> operator|=(const E&); 49 50 template <class E> 51 disable_xexpression<E, A> operator^=(const E&); 52 53 template <class E> 54 A operator=(const xexpression<E>& e); 55 56 template <class E> 57 A operator+=(const xexpression<E>& e); 58 59 template <class E> 60 A operator-=(const xexpression<E>& e); 61 62 template <class E> 63 A operator*=(const xexpression<E>& e); 64 65 template <class E> 66 A operator/=(const xexpression<E>& e); 67 68 template <class E> 69 A operator%=(const xexpression<E>& e); 70 71 template <class E> 72 A operator&=(const xexpression<E>&); 73 74 template <class E> 75 A operator|=(const xexpression<E>&); 76 77 template <class E> 78 A operator^=(const xexpression<E>&); 79 80 private: 81 82 A m_array; 83 }; 84 85 template <class A> 86 noalias_proxy<xtl::closure_type_t<A>> noalias(A&& a) noexcept; 87 88 /******************************** 89 * noalias_proxy implementation * 90 ********************************/ 91 92 template <class A> noalias_proxy(A a)93 inline noalias_proxy<A>::noalias_proxy(A a) noexcept 94 : m_array(std::forward<A>(a)) 95 { 96 } 97 98 template <class A> 99 template <class E> operator =(const E & e)100 inline auto noalias_proxy<A>::operator=(const E& e) -> disable_xexpression<E, A> 101 { 102 return m_array.assign(xscalar<E>(e)); 103 } 104 105 template <class A> 106 template <class E> operator +=(const E & e)107 inline auto noalias_proxy<A>::operator+=(const E& e) -> disable_xexpression<E, A> 108 { 109 return m_array.scalar_computed_assign(e, std::plus<>()); 110 } 111 112 template <class A> 113 template <class E> operator -=(const E & e)114 inline auto noalias_proxy<A>::operator-=(const E& e) -> disable_xexpression<E, A> 115 { 116 return m_array.scalar_computed_assign(e, std::minus<>()); 117 } 118 119 template <class A> 120 template <class E> operator *=(const E & e)121 inline auto noalias_proxy<A>::operator*=(const E& e) -> disable_xexpression<E, A> 122 { 123 return m_array.scalar_computed_assign(e, std::multiplies<>()); 124 } 125 126 template <class A> 127 template <class E> operator /=(const E & e)128 inline auto noalias_proxy<A>::operator/=(const E& e) -> disable_xexpression<E, A> 129 { 130 return m_array.scalar_computed_assign(e, std::divides<>()); 131 } 132 133 template <class A> 134 template <class E> operator %=(const E & e)135 inline auto noalias_proxy<A>::operator%=(const E& e) -> disable_xexpression<E, A> 136 { 137 return m_array.scalar_computed_assign(e, std::modulus<>()); 138 } 139 140 template <class A> 141 template <class E> operator &=(const E & e)142 inline auto noalias_proxy<A>::operator&=(const E& e) -> disable_xexpression<E, A> 143 { 144 return m_array.scalar_computed_assign(e, std::bit_and<>()); 145 } 146 147 template <class A> 148 template <class E> operator |=(const E & e)149 inline auto noalias_proxy<A>::operator|=(const E& e) -> disable_xexpression<E, A> 150 { 151 return m_array.scalar_computed_assign(e, std::bit_or<>()); 152 } 153 154 template <class A> 155 template <class E> operator ^=(const E & e)156 inline auto noalias_proxy<A>::operator^=(const E& e) -> disable_xexpression<E, A> 157 { 158 return m_array.scalar_computed_assign(e, std::bit_xor<>()); 159 } 160 161 template <class A> 162 template <class E> operator =(const xexpression<E> & e)163 inline A noalias_proxy<A>::operator=(const xexpression<E>& e) 164 { 165 return m_array.assign(e); 166 } 167 168 template <class A> 169 template <class E> operator +=(const xexpression<E> & e)170 inline A noalias_proxy<A>::operator+=(const xexpression<E>& e) 171 { 172 return m_array.plus_assign(e); 173 } 174 175 template <class A> 176 template <class E> operator -=(const xexpression<E> & e)177 inline A noalias_proxy<A>::operator-=(const xexpression<E>& e) 178 { 179 return m_array.minus_assign(e); 180 } 181 182 template <class A> 183 template <class E> operator *=(const xexpression<E> & e)184 inline A noalias_proxy<A>::operator*=(const xexpression<E>& e) 185 { 186 return m_array.multiplies_assign(e); 187 } 188 189 template <class A> 190 template <class E> operator /=(const xexpression<E> & e)191 inline A noalias_proxy<A>::operator/=(const xexpression<E>& e) 192 { 193 return m_array.divides_assign(e); 194 } 195 196 template <class A> 197 template <class E> operator %=(const xexpression<E> & e)198 inline A noalias_proxy<A>::operator%=(const xexpression<E>& e) 199 { 200 return m_array.modulus_assign(e); 201 } 202 203 template <class A> 204 template <class E> operator &=(const xexpression<E> & e)205 inline A noalias_proxy<A>::operator&=(const xexpression<E>& e) 206 { 207 return m_array.bit_and_assign(e); 208 } 209 210 template <class A> 211 template <class E> operator |=(const xexpression<E> & e)212 inline A noalias_proxy<A>::operator|=(const xexpression<E>& e) 213 { 214 return m_array.bit_or_assign(e); 215 } 216 217 template <class A> 218 template <class E> operator ^=(const xexpression<E> & e)219 inline A noalias_proxy<A>::operator^=(const xexpression<E>& e) 220 { 221 return m_array.bit_xor_assign(e); 222 } 223 224 template <class A> 225 inline noalias_proxy<xtl::closure_type_t<A>> noalias(A && a)226 noalias(A&& a) noexcept 227 { 228 return noalias_proxy<xtl::closure_type_t<A>>(a); 229 } 230 } 231 232 #endif 233