11use super :: Complex ;
22
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 } ;
57
68macro_rules! pow_impl {
79 ( $U: ty, $S: ty) => {
@@ -77,20 +79,94 @@ pow_impl!(usize, isize);
7779#[ cfg( has_i128) ]
7880pow_impl ! ( u128 , i128 ) ;
7981
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+ }
84114
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 > {
86151 type Output = Complex < T > ;
87152
88153 #[ 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)
91156 }
92157}
93158
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" ) ]
94170impl < T : Float > Pow < Complex < T > > for Complex < T > {
95171 type Output = Complex < T > ;
96172
@@ -99,3 +175,13 @@ impl<T: Float> Pow<Complex<T>> for Complex<T> {
99175 self . powc ( exp)
100176 }
101177}
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