ptr.odin 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package slice
  2. import "core:mem"
  3. ptr_add :: proc(p: $P/^$T, x: int) -> ^T {
  4. return (^T)(uintptr(p) + size_of(T)*x);
  5. }
  6. ptr_sub :: proc(p: $P/^$T, x: int) -> ^T {
  7. return #force_inline ptr_add(p, -x);
  8. }
  9. ptr_swap_non_overlapping :: proc(x, y: rawptr, len: int) {
  10. if len <= 0 {
  11. return;
  12. }
  13. if x == y { // Ignore pointers that are the same
  14. return;
  15. }
  16. Block :: distinct [4]u64;
  17. BLOCK_SIZE :: size_of(Block);
  18. i := 0;
  19. t := &Block{};
  20. for ; i + BLOCK_SIZE <= len; i += BLOCK_SIZE {
  21. a := rawptr(uintptr(x) + uintptr(i));
  22. b := rawptr(uintptr(y) + uintptr(i));
  23. mem.copy(t, a, BLOCK_SIZE);
  24. mem.copy(a, b, BLOCK_SIZE);
  25. mem.copy(b, t, BLOCK_SIZE);
  26. }
  27. if i < len {
  28. rem := len - i;
  29. a := rawptr(uintptr(x) + uintptr(i));
  30. b := rawptr(uintptr(y) + uintptr(i));
  31. mem.copy(t, a, rem);
  32. mem.copy(a, b, rem);
  33. mem.copy(b, t, rem);
  34. }
  35. }
  36. ptr_rotate :: proc(left: int, mid: ^$T, right: int) {
  37. when size_of(T) != 0 {
  38. left, mid, right := left, mid, right;
  39. // TODO(bill): Optimization with a buffer for smaller ranges
  40. if left >= right {
  41. for {
  42. ptr_swap_non_overlapping(ptr_sub(mid, right), mid, right);
  43. mid = ptr_sub(mid, right);
  44. left -= right;
  45. if left < right {
  46. break;
  47. }
  48. }
  49. } else {
  50. ptr_swap_non_overlapping(ptr_sub(mid, left), mid, left);
  51. mid = ptr_add(mid, left);
  52. right -= left;
  53. if right < left {
  54. break;
  55. }
  56. }
  57. }
  58. }