internal.odin 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package datetime
  2. // Internal helper functions for calendrical conversions
  3. import "base:intrinsics"
  4. sign :: proc "contextless" (v: i64) -> (res: i64) {
  5. if v == 0 {
  6. return 0
  7. } else if v > 0 {
  8. return 1
  9. }
  10. return -1
  11. }
  12. // Caller has to ensure y != 0
  13. divmod :: proc "contextless" (x, y: $T, loc := #caller_location) -> (a: T, r: T)
  14. where intrinsics.type_is_integer(T) {
  15. a = x / y
  16. r = x % y
  17. if (r > 0 && y < 0) || (r < 0 && y > 0) {
  18. a -= 1
  19. r += y
  20. }
  21. return a, r
  22. }
  23. // Divides and floors
  24. floor_div :: proc "contextless" (x, y: $T) -> (res: T)
  25. where intrinsics.type_is_integer(T) {
  26. res = x / y
  27. r := x % y
  28. if (r > 0 && y < 0) || (r < 0 && y > 0) {
  29. res -= 1
  30. }
  31. return res
  32. }
  33. // Half open: x mod [1..b]
  34. interval_mod :: proc "contextless" (x, a, b: i64) -> (res: i64) {
  35. if a == b {
  36. return x
  37. }
  38. return a + ((x - a) %% (b - a))
  39. }
  40. // x mod [1..b]
  41. adjusted_remainder :: proc "contextless" (x, b: i64) -> (res: i64) {
  42. m := x %% b
  43. return b if m == 0 else m
  44. }
  45. gcd :: proc "contextless" (x, y: i64) -> (res: i64) {
  46. if y == 0 {
  47. return x
  48. }
  49. m := x %% y
  50. return gcd(y, m)
  51. }
  52. lcm :: proc "contextless" (x, y: i64) -> (res: i64) {
  53. return x * y / gcd(x, y)
  54. }
  55. sum :: proc "contextless" (i: i64, f: proc "contextless" (n: i64) -> i64, cond: proc "contextless" (n: i64) -> bool) -> (res: i64) {
  56. for idx := i; cond(idx); idx += 1 {
  57. res += f(idx)
  58. }
  59. return
  60. }
  61. product :: proc "contextless" (i: i64, f: proc "contextless" (n: i64) -> i64, cond: proc "contextless" (n: i64) -> bool) -> (res: i64) {
  62. res = 1
  63. for idx := i; cond(idx); idx += 1 {
  64. res *= f(idx)
  65. }
  66. return
  67. }
  68. smallest :: proc "contextless" (k: i64, cond: proc "contextless" (n: i64) -> bool) -> (d: i64) {
  69. k := k
  70. for !cond(k) {
  71. k += 1
  72. }
  73. return k
  74. }
  75. biggest :: proc "contextless" (k: i64, cond: proc "contextless" (n: i64) -> bool) -> (d: i64) {
  76. k := k
  77. for !cond(k) {
  78. k -= 1
  79. }
  80. return k
  81. }