slice.odin 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. package slice
  2. import "core:intrinsics"
  3. import "core:builtin"
  4. import "core:math/bits"
  5. import "core:mem"
  6. _ :: intrinsics
  7. _ :: builtin
  8. _ :: bits
  9. _ :: mem
  10. /*
  11. Turn a pointer and a length into a slice.
  12. */
  13. from_ptr :: proc "contextless" (ptr: ^$T, count: int) -> []T {
  14. return ([^]T)(ptr)[:count]
  15. }
  16. /*
  17. Turn a pointer and a length into a byte slice.
  18. */
  19. bytes_from_ptr :: proc "contextless" (ptr: rawptr, byte_count: int) -> []byte {
  20. return ([^]byte)(ptr)[:byte_count]
  21. }
  22. /*
  23. Turn a slice into a byte slice.
  24. See `slice.reinterpret` to go the other way.
  25. */
  26. to_bytes :: proc "contextless" (s: []$T) -> []byte {
  27. return ([^]byte)(raw_data(s))[:len(s) * size_of(T)]
  28. }
  29. /*
  30. Turn a slice of one type, into a slice of another type.
  31. Only converts the type and length of the slice itself.
  32. The length is rounded down to the nearest whole number of items.
  33. ```
  34. large_items := []i64{1, 2, 3, 4}
  35. small_items := slice.reinterpret([]i32, large_items)
  36. assert(len(small_items) == 8)
  37. ```
  38. ```
  39. small_items := []byte{1, 0, 0, 0, 0, 0, 0, 0,
  40. 2, 0, 0, 0}
  41. large_items := slice.reinterpret([]i64, small_items)
  42. assert(len(large_items) == 1) // only enough bytes to make 1 x i64; two would need at least 8 bytes.
  43. ```
  44. */
  45. reinterpret :: proc "contextless" ($T: typeid/[]$U, s: []$V) -> []U {
  46. bytes := to_bytes(s)
  47. n := len(bytes) / size_of(U)
  48. return ([^]U)(raw_data(bytes))[:n]
  49. }
  50. swap :: proc(array: $T/[]$E, a, b: int) {
  51. when size_of(E) > 8 {
  52. ptr_swap_non_overlapping(&array[a], &array[b], size_of(E))
  53. } else {
  54. array[a], array[b] = array[b], array[a]
  55. }
  56. }
  57. swap_between :: proc(a, b: $T/[]$E) {
  58. n := builtin.min(len(a), len(b))
  59. if n >= 0 {
  60. ptr_swap_overlapping(&a[0], &b[0], size_of(E)*n)
  61. }
  62. }
  63. reverse :: proc(array: $T/[]$E) {
  64. n := len(array)/2
  65. for i in 0..<n {
  66. a, b := i, len(array)-i-1
  67. array[a], array[b] = array[b], array[a]
  68. }
  69. }
  70. contains :: proc(array: $T/[]$E, value: E) -> bool where intrinsics.type_is_comparable(E) {
  71. _, found := linear_search(array, value)
  72. return found
  73. }
  74. linear_search :: proc(array: $A/[]$T, key: T) -> (index: int, found: bool)
  75. where intrinsics.type_is_comparable(T) #no_bounds_check {
  76. for x, i in array {
  77. if x == key {
  78. return i, true
  79. }
  80. }
  81. return -1, false
  82. }
  83. linear_search_proc :: proc(array: $A/[]$T, f: proc(T) -> bool) -> (index: int, found: bool) #no_bounds_check {
  84. for x, i in array {
  85. if f(x) {
  86. return i, true
  87. }
  88. }
  89. return -1, false
  90. }
  91. binary_search :: proc(array: $A/[]$T, key: T) -> (index: int, found: bool)
  92. where intrinsics.type_is_ordered(T) #no_bounds_check {
  93. n := len(array)
  94. switch n {
  95. case 0:
  96. return -1, false
  97. case 1:
  98. if array[0] == key {
  99. return 0, true
  100. }
  101. return -1, false
  102. }
  103. lo, hi := 0, n-1
  104. for array[hi] != array[lo] && key >= array[lo] && key <= array[hi] {
  105. when intrinsics.type_is_ordered_numeric(T) {
  106. // NOTE(bill): This is technically interpolation search
  107. m := lo + int((key - array[lo]) * T(hi - lo) / (array[hi] - array[lo]))
  108. } else {
  109. m := lo + (hi - lo)/2
  110. }
  111. switch {
  112. case array[m] < key:
  113. lo = m + 1
  114. case key < array[m]:
  115. hi = m - 1
  116. case:
  117. return m, true
  118. }
  119. }
  120. if key == array[lo] {
  121. return lo, true
  122. }
  123. return -1, false
  124. }
  125. equal :: proc(a, b: $T/[]$E) -> bool where intrinsics.type_is_comparable(E) {
  126. if len(a) != len(b) {
  127. return false
  128. }
  129. when intrinsics.type_is_simple_compare(E) {
  130. return mem.compare_ptrs(raw_data(a), raw_data(b), len(a)*size_of(E)) == 0
  131. } else {
  132. for i in 0..<len(a) {
  133. if a[i] != b[i] {
  134. return false
  135. }
  136. }
  137. return true
  138. }
  139. }
  140. simple_equal :: proc(a, b: $T/[]$E) -> bool where intrinsics.type_is_simple_compare(E) {
  141. if len(a) != len(b) {
  142. return false
  143. }
  144. return mem.compare_ptrs(raw_data(a), raw_data(b), len(a)*size_of(E)) == 0
  145. }
  146. /*
  147. return the prefix length common between slices `a` and `b`.
  148. slice.prefix_length([]u8{1, 2, 3, 4}, []u8{1}) -> 1
  149. slice.prefix_length([]u8{1, 2, 3, 4}, []u8{1, 2, 3}) -> 3
  150. slice.prefix_length([]u8{1, 2, 3, 4}, []u8{2, 3, 4}) -> 0
  151. */
  152. prefix_length :: proc(a, b: $T/[]$E) -> (n: int) where intrinsics.type_is_comparable(E) {
  153. _len := builtin.min(len(a), len(b))
  154. #no_bounds_check for n < _len && a[n] == b[n] {
  155. n += 1
  156. }
  157. return
  158. }
  159. has_prefix :: proc(array: $T/[]$E, needle: E) -> bool where intrinsics.type_is_comparable(E) {
  160. n := len(needle)
  161. if len(array) >= n {
  162. return equal(array[:n], needle)
  163. }
  164. return false
  165. }
  166. has_suffix :: proc(array: $T/[]$E, needle: E) -> bool where intrinsics.type_is_comparable(E) {
  167. array := array
  168. m, n := len(array), len(needle)
  169. if m >= n {
  170. return equal(array[m-n:], needle)
  171. }
  172. return false
  173. }
  174. fill :: proc(array: $T/[]$E, value: E) #no_bounds_check {
  175. if len(array) <= 0 {
  176. return
  177. }
  178. array[0] = value
  179. for i := 1; i < len(array); i *= 2 {
  180. copy(array[i:], array[:i])
  181. }
  182. }
  183. rotate_left :: proc(array: $T/[]$E, mid: int) {
  184. n := len(array)
  185. m := mid %% n
  186. k := n - m
  187. p := raw_data(array)
  188. ptr_rotate(mid, ptr_add(p, mid), k)
  189. }
  190. rotate_right :: proc(array: $T/[]$E, k: int) {
  191. rotate_left(array, -k)
  192. }
  193. swap_with_slice :: proc(a, b: $T/[]$E, loc := #caller_location) {
  194. assert(len(a) == len(b), "miss matching slice lengths", loc)
  195. ptr_swap_non_overlapping(raw_data(a), raw_data(b), len(a)*size_of(E))
  196. }
  197. concatenate :: proc(a: []$T/[]$E, allocator := context.allocator) -> (res: T) {
  198. if len(a) == 0 {
  199. return
  200. }
  201. n := 0
  202. for s in a {
  203. n += len(s)
  204. }
  205. res = make(T, n, allocator)
  206. i := 0
  207. for s in a {
  208. i += copy(res[i:], s)
  209. }
  210. return
  211. }
  212. // copies a slice into a new slice
  213. clone :: proc(a: $T/[]$E, allocator := context.allocator) -> []E {
  214. d := make([]E, len(a), allocator)
  215. copy(d[:], a)
  216. return d
  217. }
  218. // copies slice into a new dynamic array
  219. clone_to_dynamic :: proc(a: $T/[]$E, allocator := context.allocator) -> [dynamic]E {
  220. d := make([dynamic]E, len(a), allocator)
  221. copy(d[:], a)
  222. return d
  223. }
  224. to_dynamic :: clone_to_dynamic
  225. // Converts slice into a dynamic array without cloning or allocating memory
  226. into_dynamic :: proc(a: $T/[]$E) -> [dynamic]E {
  227. s := transmute(mem.Raw_Slice)a
  228. d := mem.Raw_Dynamic_Array{
  229. data = s.data,
  230. len = 0,
  231. cap = s.len,
  232. allocator = mem.nil_allocator(),
  233. }
  234. return transmute([dynamic]E)d
  235. }
  236. length :: proc(a: $T/[]$E) -> int {
  237. return len(a)
  238. }
  239. is_empty :: proc(a: $T/[]$E) -> bool {
  240. return len(a) == 0
  241. }
  242. split_at :: proc(array: $T/[]$E, index: int) -> (a, b: T) {
  243. return array[:index], array[index:]
  244. }
  245. split_first :: proc(array: $T/[]$E) -> (first: E, rest: T) {
  246. return array[0], array[1:]
  247. }
  248. split_last :: proc(array: $T/[]$E) -> (rest: T, last: E) {
  249. n := len(array)-1
  250. return array[:n], array[n]
  251. }
  252. first :: proc(array: $T/[]$E) -> E {
  253. return array[0]
  254. }
  255. last :: proc(array: $T/[]$E) -> E {
  256. return array[len(array)-1]
  257. }
  258. first_ptr :: proc(array: $T/[]$E) -> ^E {
  259. if len(array) != 0 {
  260. return &array[0]
  261. }
  262. return nil
  263. }
  264. last_ptr :: proc(array: $T/[]$E) -> ^E {
  265. if len(array) != 0 {
  266. return &array[len(array)-1]
  267. }
  268. return nil
  269. }
  270. get :: proc(array: $T/[]$E, index: int) -> (value: E, ok: bool) {
  271. if uint(index) < len(array) {
  272. value = array[index]
  273. ok = true
  274. }
  275. return
  276. }
  277. get_ptr :: proc(array: $T/[]$E, index: int) -> (value: ^E, ok: bool) {
  278. if uint(index) < len(array) {
  279. value = &array[index]
  280. ok = true
  281. }
  282. return
  283. }
  284. as_ptr :: proc(array: $T/[]$E) -> [^]E {
  285. return raw_data(array)
  286. }
  287. mapper :: proc(s: $S/[]$U, f: proc(U) -> $V, allocator := context.allocator) -> []V {
  288. r := make([]V, len(s), allocator)
  289. for v, i in s {
  290. r[i] = f(v)
  291. }
  292. return r
  293. }
  294. reduce :: proc(s: $S/[]$U, initializer: $V, f: proc(V, U) -> V) -> V {
  295. r := initializer
  296. for v in s {
  297. r = f(r, v)
  298. }
  299. return r
  300. }
  301. filter :: proc(s: $S/[]$U, f: proc(U) -> bool, allocator := context.allocator) -> S {
  302. r := make([dynamic]U, 0, 0, allocator)
  303. for v in s {
  304. if f(v) {
  305. append(&r, v)
  306. }
  307. }
  308. return r[:]
  309. }
  310. scanner :: proc (s: $S/[]$U, initializer: $V, f: proc(V, U) -> V, allocator := context.allocator) -> []V {
  311. if len(s) == 0 { return {} }
  312. res := make([]V, len(s), allocator)
  313. p := as_ptr(s)
  314. q := as_ptr(res)
  315. r := initializer
  316. for l := len(s); l > 0; l -= 1 {
  317. r = f(r, p[0])
  318. q[0] = r
  319. p = p[1:]
  320. q = q[1:]
  321. }
  322. return res
  323. }
  324. min :: proc(s: $S/[]$T) -> (res: T, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok {
  325. if len(s) != 0 {
  326. res = s[0]
  327. ok = true
  328. for v in s[1:] {
  329. res = builtin.min(res, v)
  330. }
  331. }
  332. return
  333. }
  334. max :: proc(s: $S/[]$T) -> (res: T, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok {
  335. if len(s) != 0 {
  336. res = s[0]
  337. ok = true
  338. for v in s[1:] {
  339. res = builtin.max(res, v)
  340. }
  341. }
  342. return
  343. }
  344. min_max :: proc(s: $S/[]$T) -> (min, max: T, ok: bool) where intrinsics.type_is_ordered(T) {
  345. if len(s) != 0 {
  346. min, max = s[0], s[0]
  347. ok = true
  348. for v in s[1:] {
  349. min = builtin.min(min, v)
  350. max = builtin.max(max, v)
  351. }
  352. }
  353. return
  354. }
  355. any_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) {
  356. for v in s {
  357. if v == value {
  358. return true
  359. }
  360. }
  361. return false
  362. }
  363. none_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) {
  364. for v in s {
  365. if v == value {
  366. return false
  367. }
  368. }
  369. return true
  370. }
  371. all_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) {
  372. if len(s) == 0 {
  373. return false
  374. }
  375. for v in s {
  376. if v != value {
  377. return false
  378. }
  379. }
  380. return true
  381. }
  382. any_of_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> bool {
  383. for v in s {
  384. if f(v) {
  385. return true
  386. }
  387. }
  388. return false
  389. }
  390. none_of_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> bool {
  391. for v in s {
  392. if f(v) {
  393. return false
  394. }
  395. }
  396. return true
  397. }
  398. all_of_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> bool {
  399. if len(s) == 0 {
  400. return false
  401. }
  402. for v in s {
  403. if !f(v) {
  404. return false
  405. }
  406. }
  407. return true
  408. }
  409. count :: proc(s: $S/[]$T, value: T) -> (n: int) where intrinsics.type_is_comparable(T) {
  410. for v in s {
  411. if v == value {
  412. n += 1
  413. }
  414. }
  415. return
  416. }
  417. count_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> (n: int) {
  418. for v in s {
  419. if f(v) {
  420. n += 1
  421. }
  422. }
  423. return
  424. }
  425. dot_product :: proc(a, b: $S/[]$T) -> (r: T, ok: bool)
  426. where intrinsics.type_is_numeric(T) {
  427. if len(a) != len(b) {
  428. return
  429. }
  430. #no_bounds_check for _, i in a {
  431. r += a[i] * b[i]
  432. }
  433. return r, true
  434. }
  435. // Convert a pointer to an enumerated array to a slice of the element type
  436. enumerated_array :: proc(ptr: ^$T) -> []intrinsics.type_elem_type(T)
  437. where intrinsics.type_is_enumerated_array(T) {
  438. return ([^]intrinsics.type_elem_type(T))(ptr)[:len(T)]
  439. }