internal.odin 1.8 KB

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