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