diff --git a/core/slice/ptr.odin b/core/slice/ptr.odin index 0a3dea957..9074932ae 100644 --- a/core/slice/ptr.odin +++ b/core/slice/ptr.odin @@ -1,5 +1,6 @@ package slice +import "core:builtin" import "core:mem" ptr_add :: proc(p: $P/^$T, x: int) -> ^T { @@ -43,6 +44,29 @@ ptr_swap_non_overlapping :: proc(x, y: rawptr, len: int) { } } +ptr_swap_overlapping :: proc(x, y: rawptr, len: int) { + if len <= 0 { + return + } + if x == y { + return + } + + N :: 512 + buffer: [N]byte = --- + + a, b := ([^]byte)(x), ([^]byte)(y) + + for n := len; n > 0; n -= N { + m := builtin.min(n, N) + mem.copy(&buffer, a, m) + mem.copy(a, b, m) + mem.copy(b, &buffer, m) + + a, b = a[N:], b[N:] + } +} + ptr_rotate :: proc(left: int, mid: ^$T, right: int) { when size_of(T) != 0 { diff --git a/core/slice/slice.odin b/core/slice/slice.odin index ba14854a0..1dd777ccc 100644 --- a/core/slice/slice.odin +++ b/core/slice/slice.odin @@ -11,7 +11,7 @@ _ :: bits _ :: mem -swap :: proc(array: $T/[]$E, a, b: int, loc := #caller_location) { +swap :: proc(array: $T/[]$E, a, b: int) { when size_of(E) > 8 { ptr_swap_non_overlapping(&array[a], &array[b], size_of(E)) } else { @@ -19,6 +19,13 @@ swap :: proc(array: $T/[]$E, a, b: int, loc := #caller_location) { } } +swap_between :: proc(a, b: $T/[]$E) { + n := min(len(a), len(b)) + if n >= 0 { + ptr_swap_overlapping(&a[0], &b[0], size_of(E)*n) + } +} + reverse :: proc(array: $T/[]$E) { n := len(array)/2