lenientops.nim 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2017 Nim contributors
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## This module offers implementations of common binary operations
  10. ## like ``+``, ``-``, ``*``, ``/`` and comparison operations,
  11. ## which work for mixed float/int operands.
  12. ## All operations convert the integer operand into the
  13. ## type of the float operand. For numerical expressions, the return
  14. ## type is always the type of the float involved in the expresssion,
  15. ## i.e., there is no auto conversion from float32 to float64.
  16. ##
  17. ## Note: In general, auto-converting from int to float loses
  18. ## information, which is why these operators live in a separate
  19. ## module. Use with care.
  20. ##
  21. ## Regarding binary comparison, this module only provides unequal operators.
  22. ## The equality operator ``==`` is omitted, because depending on the use case
  23. ## either casting to float or rounding to int might be preferred, and users
  24. ## should make an explicit choice.
  25. import typetraits
  26. proc `+`*[I: SomeInteger, F: SomeFloat](i: I, f: F): F {.noSideEffect, inline.} =
  27. F(i) + f
  28. proc `+`*[I: SomeInteger, F: SomeFloat](f: F, i: I): F {.noSideEffect, inline.} =
  29. f + F(i)
  30. proc `-`*[I: SomeInteger, F: SomeFloat](i: I, f: F): F {.noSideEffect, inline.} =
  31. F(i) - f
  32. proc `-`*[I: SomeInteger, F: SomeFloat](f: F, i: I): F {.noSideEffect, inline.} =
  33. f - F(i)
  34. proc `*`*[I: SomeInteger, F: SomeFloat](i: I, f: F): F {.noSideEffect, inline.} =
  35. F(i) * f
  36. proc `*`*[I: SomeInteger, F: SomeFloat](f: F, i: I): F {.noSideEffect, inline.} =
  37. f * F(i)
  38. proc `/`*[I: SomeInteger, F: SomeFloat](i: I, f: F): F {.noSideEffect, inline.} =
  39. F(i) / f
  40. proc `/`*[I: SomeInteger, F: SomeFloat](f: F, i: I): F {.noSideEffect, inline.} =
  41. f / F(i)
  42. proc `<`*[I: SomeInteger, F: SomeFloat](i: I, f: F): bool {.noSideEffect, inline.} =
  43. F(i) < f
  44. proc `<`*[I: SomeInteger, F: SomeFloat](f: F, i: I): bool {.noSideEffect, inline.} =
  45. f < F(i)
  46. proc `<=`*[I: SomeInteger, F: SomeFloat](i: I, f: F): bool {.noSideEffect, inline.} =
  47. F(i) <= f
  48. proc `<=`*[I: SomeInteger, F: SomeFloat](f: F, i: I): bool {.noSideEffect, inline.} =
  49. f <= F(i)
  50. # Note that we must not defined `>=` and `>`, because system.nim already has a
  51. # template with signature (x, y: untyped): untyped, which would lead to
  52. # ambigous calls.