Skip to content

Commit

Permalink
Streamline Complex -> Real coercion
Browse files Browse the repository at this point in the history
- Make coerce-to-real method a private method
  It was not marked as implementation detail, but also not tested
  nor documented, so making it a private method seems the right
  thing to do.
- Move Failure creation to separate private method, to allow for
  easier inlining of the hot path
- Make coercion to Rat / FatRat a multi, for better dispatchability
  and inlineability
  • Loading branch information
lizmat committed Feb 18, 2022
1 parent 7bc572e commit e3b836a
Showing 1 changed file with 28 additions and 9 deletions.
37 changes: 28 additions & 9 deletions src/core.c/Complex.pm6
Expand Up @@ -45,21 +45,40 @@ my class Complex is Cool does Numeric {
self.re.isNaN || self.im.isNaN;
}

method coerce-to-real(Complex:D: $exception-target) {
method !coerce-to-real-failed($target) {
Failure.new(
X::Numeric::Real.new(
:$target,
reason => "imaginary part not zero",
source => self
)
)
}
method !coerce-to-real($target) {
$!im 0e0
?? $!re
!! Failure.new(X::Numeric::Real.new(target => $exception-target, reason => "imaginary part not zero", source => self))
!! self!coerce-to-real-failed($target)
}
multi method Real(Complex:D:) { self.coerce-to-real(Real); }
multi method Real(Complex:D:) { self!coerce-to-real(Real) }

# should probably be eventually supplied by role Numeric
method Num(Complex:D:) { self.coerce-to-real(Num).Num; }
method Int(Complex:D:) { self.coerce-to-real(Int).Int; }
method Rat(Complex:D: $epsilon?) {
self.coerce-to-real(Rat).Rat( |($epsilon // Empty) );
method Num(Complex:D:) { self!coerce-to-real(Num).Num }
method Int(Complex:D:) { self!coerce-to-real(Int).Int }

proto method Rat(|) {*}
multi method Rat(Complex:D:) {
self!coerce-to-real(Rat).Rat
}
multi method Rat(Complex:D: $epsilon) {
self!coerce-to-real(Rat).Rat: $epsilon
}

proto method FatRat(|) {*}
multi method FatRat(Complex:D:) {
self!coerce-to-real(FatRat).FatRat
}
method FatRat(Complex:D: $epsilon?) {
self.coerce-to-real(FatRat).FatRat( |($epsilon // Empty) );
multi method FatRat(Complex:D: $epsilon?) {
self!coerce-to-real(FatRat).FatRat: $epsilon
}

multi method Bool(Complex:D:) {
Expand Down

0 comments on commit e3b836a

Please sign in to comment.