diff --git a/src/implementations/BigFloat.jl b/src/implementations/BigFloat.jl index f72ad5b0..2aa0929c 100644 --- a/src/implementations/BigFloat.jl +++ b/src/implementations/BigFloat.jl @@ -61,6 +61,10 @@ function operate_to!(output::BigFloat, ::typeof(+), a::BigFloat, b::BigFloat) return output end +operate_to!(out::BigFloat, ::typeof(+), a::BigFloat) = operate_to!(out, copy, a) + +operate!(::typeof(+), a::BigFloat) = a + # - promote_operation(::typeof(-), ::Vararg{Type{BigFloat},N}) where {N} = BigFloat @@ -78,32 +82,36 @@ function operate_to!(output::BigFloat, ::typeof(-), a::BigFloat, b::BigFloat) return output end -function operate!(::typeof(-), x::BigFloat) +function operate_to!(o::BigFloat, ::typeof(-), x::BigFloat) ccall( (:mpfr_neg, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Base.MPFR.MPFRRoundingMode), - x, + o, x, Base.MPFR.ROUNDING_MODE[], ) - return x + return o end +operate!(::typeof(-), x::BigFloat) = operate_to!(x, -, x) + # Base.abs -function operate!(::typeof(Base.abs), x::BigFloat) +function operate_to!(o::BigFloat, ::typeof(Base.abs), x::BigFloat) ccall( (:mpfr_abs, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Base.MPFR.MPFRRoundingMode), - x, + o, x, Base.MPFR.ROUNDING_MODE[], ) - return x + return o end +operate!(::typeof(Base.abs), x::BigFloat) = operate_to!(x, abs, x) + # * promote_operation(::typeof(*), ::Type{BigFloat}, ::Type{BigFloat}) = BigFloat @@ -121,6 +129,10 @@ function operate_to!(output::BigFloat, ::typeof(*), a::BigFloat, b::BigFloat) return output end +operate_to!(out::BigFloat, ::typeof(*), a::BigFloat) = operate_to!(out, copy, a) + +operate!(::typeof(*), a::BigFloat) = a + # Base.fma function promote_operation( diff --git a/src/implementations/BigInt.jl b/src/implementations/BigInt.jl index 36aa8c45..c6102115 100644 --- a/src/implementations/BigInt.jl +++ b/src/implementations/BigInt.jl @@ -33,6 +33,10 @@ function operate_to!(output::BigInt, ::typeof(+), a::BigInt, b::BigInt) return Base.GMP.MPZ.add!(output, a, b) end +operate_to!(out::BigInt, ::typeof(+), a::BigInt) = operate_to!(out, copy, a) + +operate!(::typeof(+), a::BigInt) = a + # - promote_operation(::typeof(-), ::Vararg{Type{BigInt},N}) where {N} = BigInt @@ -41,6 +45,10 @@ function operate_to!(output::BigInt, ::typeof(-), a::BigInt, b::BigInt) return Base.GMP.MPZ.sub!(output, a, b) end +operate_to!(out::BigInt, ::typeof(-), a::BigInt) = Base.GMP.MPZ.neg!(out, a) + +operate!(::typeof(-), a::BigInt) = operate_to!(a, -, a) + # * promote_operation(::typeof(*), ::Type{BigInt}, ::Type{BigInt}) = BigInt @@ -49,6 +57,10 @@ function operate_to!(output::BigInt, ::typeof(*), a::BigInt, b::BigInt) return Base.GMP.MPZ.mul!(output, a, b) end +operate_to!(out::BigInt, ::typeof(*), a::BigInt) = operate_to!(out, copy, a) + +operate!(::typeof(*), a::BigInt) = a + promote_operation(::typeof(div), ::Type{BigInt}, ::Type{BigInt}) = BigInt function operate_to!(output::BigInt, ::typeof(div), a::BigInt, b::BigInt) diff --git a/src/implementations/Rational.jl b/src/implementations/Rational.jl index 2c293138..4e2c4a78 100644 --- a/src/implementations/Rational.jl +++ b/src/implementations/Rational.jl @@ -118,6 +118,23 @@ function operate_to!(output::Rational, ::typeof(+), x::Rational, y::Rational) return output end +function operate_to!(out::Q, ::typeof(+), x::Q) where {Q<:Rational} + return operate_to!(out, copy, x) +end + +operate!(::typeof(+), x::Rational) = x + +function operate_to!(out::Q, ::typeof(-), x::Q) where {Q<:Rational} + operate_to!(out.num, -, x.num) + operate_to!(out.den, copy, x.den) + return out +end + +function operate!(::typeof(-), x::Rational) + operate!(-, x.num) + return x +end + # * function promote_operation( @@ -162,6 +179,12 @@ function operate_to!(output::Rational, ::typeof(*), x::Rational, y::Rational) ) end +function operate_to!(out::Q, ::typeof(*), x::Q) where {Q<:Rational} + return operate_to!(out, copy, x) +end + +operate!(::typeof(*), x::Rational) = x + # gcd function promote_operation( diff --git a/test/interface.jl b/test/interface.jl index bfbfc8e9..8c7388e6 100644 --- a/test/interface.jl +++ b/test/interface.jl @@ -126,3 +126,26 @@ end @test MA.similar_array_type(BitArray{2}, Int) == Array{Int,2} @test MA.similar_array_type(BitArray{2}, Bool) == BitArray{2} end + +@testset "unary op(::$T)" for T in ( + Float64, + BigFloat, + Int, + BigInt, + Rational{Int}, + Rational{BigInt}, +) + @test MA.operate!!(+, T(7)) == 7 + @test MA.operate!!(*, T(7)) == 7 + @test MA.operate!!(-, T(7)) == -7 + + @test MA.operate_to!!(T(6), +, T(7)) == 7 + @test MA.operate_to!!(T(6), *, T(7)) == 7 + @test MA.operate_to!!(T(6), -, T(7)) == -7 + + @test MA.operate!!(abs, T(7)) == 7 + @test MA.operate!!(abs, T(-7)) == 7 + + @test MA.operate_to!!(T(6), abs, T(7)) == 7 + @test MA.operate_to!!(T(6), abs, T(-7)) == 7 +end