1. ## Order enumeration, for cmp and <=>
  2. my enum Order (:Less(-1), :Same(0), :More(1));
  3. role Rational { ... }
  4. sub ORDER(int $i) {
  5. nqp::iseq_i($i,0) ?? Same !! nqp::islt_i($i,0) ?? Less !! More
  6. }
  7. proto sub infix:<cmp>(Mu $, Mu $) is pure { * }
  8. multi sub infix:<cmp>(\a, \b) {
  9. nqp::eqaddr(a,b)
  10. ?? Same
  11. !! a.Stringy cmp b.Stringy
  12. }
  13. multi sub infix:<cmp>(Real:D \a, \b) {
  14. a === -Inf
  15. ?? Less
  16. !! a === Inf
  17. ?? More
  18. !! a.Stringy cmp b.Stringy
  19. }
  20. multi sub infix:<cmp>(\a, Real:D \b) {
  21. b === Inf
  22. ?? Less
  23. !! b === -Inf
  24. ?? More
  25. !! a.Stringy cmp b.Stringy
  26. }
  27. multi sub infix:<cmp>(Real:D \a, Real:D \b) {
  28. (nqp::istype(a, Rational) && nqp::isfalse(a.denominator))
  29. || (nqp::istype(b, Rational) && nqp::isfalse(b.denominator))
  30. ?? a.Bridge cmp b.Bridge
  31. !! a === -Inf || b === Inf
  32. ?? Less
  33. !! a === Inf || b === -Inf
  34. ?? More
  35. !! a.Bridge cmp b.Bridge
  36. }
  37. multi sub infix:<cmp>(Int:D \a, Rational:D \b) {
  38. a.isNaN || b.isNaN ?? a.Num cmp b.Num !! a <=> b
  39. }
  40. multi sub infix:<cmp>(Rational:D \a, Int:D \b) {
  41. a.isNaN || b.isNaN ?? a.Num cmp b.Num !! a <=> b
  42. }
  43. multi sub infix:<cmp>(Int:D \a, Int:D \b) {
  44. ORDER(nqp::cmp_I(nqp::decont(a), nqp::decont(b)))
  45. }
  46. multi sub infix:<cmp>(int $a, int $b) {
  47. ORDER(nqp::cmp_i($a, $b))
  48. }
  49. multi sub infix:«<=>»(Int:D \a, Int:D \b) {
  50. ORDER(nqp::cmp_I(nqp::decont(a), nqp::decont(b)))
  51. }
  52. multi sub infix:«<=>»(int $a, int $b) {
  53. ORDER(nqp::cmp_i($a, $b))
  54. }