1
1
use super :: Complex ;
2
2
3
- use std:: ops:: Neg ;
4
- use traits:: { Float , Num , One , Pow } ;
3
+ use core:: ops:: Neg ;
4
+ #[ cfg( feature = "std" ) ]
5
+ use traits:: Float ;
6
+ use traits:: { Num , One , Pow } ;
5
7
6
8
macro_rules! pow_impl {
7
9
( $U: ty, $S: ty) => {
@@ -77,20 +79,94 @@ pow_impl!(usize, isize);
77
79
#[ cfg( has_i128) ]
78
80
pow_impl ! ( u128 , i128 ) ;
79
81
80
- // Note: the impls above are for `&Complex<T>`, while those below are for `Complex<T>`. This is
81
- // fine since `Float: Copy` anyway, but it's also necessary to avoid conflicting implementations.
82
- // Otherwise rustc would insist that those `Pow<{integer}>` impls could overlap with `Pow<T>` if
83
- // integers ever implement `Float`, though of course we know they won't...
82
+ // Note: we can't add `impl<T: Float> Pow<T> for Complex<T>` because new blanket impls are a
83
+ // breaking change. Someone could already have their own `F` and `impl Pow<F> for Complex<F>`
84
+ // which would conflict. We can't even do this in a new semantic version, because we have to
85
+ // gate it on the "std" feature, and features can't add breaking changes either.
86
+
87
+ macro_rules! powf_impl {
88
+ ( $F: ty) => {
89
+ #[ cfg( feature = "std" ) ]
90
+ impl <' a, T : Float > Pow <$F> for & ' a Complex <T >
91
+ where
92
+ $F: Into <T >,
93
+ {
94
+ type Output = Complex <T >;
95
+
96
+ #[ inline]
97
+ fn pow( self , exp: $F) -> Self :: Output {
98
+ self . powf( exp. into( ) )
99
+ }
100
+ }
101
+
102
+ #[ cfg( feature = "std" ) ]
103
+ impl <' a, ' b, T : Float > Pow <& ' b $F> for & ' a Complex <T >
104
+ where
105
+ $F: Into <T >,
106
+ {
107
+ type Output = Complex <T >;
108
+
109
+ #[ inline]
110
+ fn pow( self , & exp: & $F) -> Self :: Output {
111
+ self . powf( exp. into( ) )
112
+ }
113
+ }
84
114
85
- impl < T : Float > Pow < T > for Complex < T > {
115
+ #[ cfg( feature = "std" ) ]
116
+ impl <T : Float > Pow <$F> for Complex <T >
117
+ where
118
+ $F: Into <T >,
119
+ {
120
+ type Output = Complex <T >;
121
+
122
+ #[ inline]
123
+ fn pow( self , exp: $F) -> Self :: Output {
124
+ self . powf( exp. into( ) )
125
+ }
126
+ }
127
+
128
+ #[ cfg( feature = "std" ) ]
129
+ impl <' b, T : Float > Pow <& ' b $F> for Complex <T >
130
+ where
131
+ $F: Into <T >,
132
+ {
133
+ type Output = Complex <T >;
134
+
135
+ #[ inline]
136
+ fn pow( self , & exp: & $F) -> Self :: Output {
137
+ self . powf( exp. into( ) )
138
+ }
139
+ }
140
+ } ;
141
+ }
142
+
143
+ powf_impl ! ( f32 ) ;
144
+ powf_impl ! ( f64 ) ;
145
+
146
+ // These blanket impls are OK, because both the target type and the trait parameter would be
147
+ // foreign to anyone else trying to implement something that would overlap, raising E0117.
148
+
149
+ #[ cfg( feature = "std" ) ]
150
+ impl < ' a , T : Float > Pow < Complex < T > > for & ' a Complex < T > {
86
151
type Output = Complex < T > ;
87
152
88
153
#[ inline]
89
- fn pow ( self , exp : T ) -> Self :: Output {
90
- self . powf ( exp)
154
+ fn pow ( self , exp : Complex < T > ) -> Self :: Output {
155
+ self . powc ( exp)
91
156
}
92
157
}
93
158
159
+ #[ cfg( feature = "std" ) ]
160
+ impl < ' a , ' b , T : Float > Pow < & ' b Complex < T > > for & ' a Complex < T > {
161
+ type Output = Complex < T > ;
162
+
163
+ #[ inline]
164
+ fn pow ( self , & exp: & ' b Complex < T > ) -> Self :: Output {
165
+ self . powc ( exp)
166
+ }
167
+ }
168
+
169
+ #[ cfg( feature = "std" ) ]
94
170
impl < T : Float > Pow < Complex < T > > for Complex < T > {
95
171
type Output = Complex < T > ;
96
172
@@ -99,3 +175,13 @@ impl<T: Float> Pow<Complex<T>> for Complex<T> {
99
175
self . powc ( exp)
100
176
}
101
177
}
178
+
179
+ #[ cfg( feature = "std" ) ]
180
+ impl < ' b , T : Float > Pow < & ' b Complex < T > > for Complex < T > {
181
+ type Output = Complex < T > ;
182
+
183
+ #[ inline]
184
+ fn pow ( self , & exp: & ' b Complex < T > ) -> Self :: Output {
185
+ self . powc ( exp)
186
+ }
187
+ }
0 commit comments