slice.odin 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. package slice
  2. import "core:intrinsics"
  3. import "core:builtin"
  4. import "core:math/bits"
  5. import "core:runtime"
  6. _ :: intrinsics
  7. _ :: builtin
  8. _ :: bits
  9. _ :: runtime
  10. /*
  11. Turn a pointer and a length into a slice.
  12. */
  13. @(require_results)
  14. from_ptr :: proc "contextless" (ptr: ^$T, count: int) -> []T {
  15. return ([^]T)(ptr)[:count]
  16. }
  17. /*
  18. Turn a pointer and a length into a byte slice.
  19. */
  20. @(require_results)
  21. bytes_from_ptr :: proc "contextless" (ptr: rawptr, byte_count: int) -> []byte {
  22. return ([^]byte)(ptr)[:byte_count]
  23. }
  24. /*
  25. Turn a slice into a byte slice.
  26. See `slice.reinterpret` to go the other way.
  27. */
  28. @(require_results)
  29. to_bytes :: proc "contextless" (s: []$T) -> []byte {
  30. return ([^]byte)(raw_data(s))[:len(s) * size_of(T)]
  31. }
  32. /*
  33. Turn a slice of one type, into a slice of another type.
  34. Only converts the type and length of the slice itself.
  35. The length is rounded down to the nearest whole number of items.
  36. ```
  37. large_items := []i64{1, 2, 3, 4}
  38. small_items := slice.reinterpret([]i32, large_items)
  39. assert(len(small_items) == 8)
  40. ```
  41. ```
  42. small_items := []byte{1, 0, 0, 0, 0, 0, 0, 0,
  43. 2, 0, 0, 0}
  44. large_items := slice.reinterpret([]i64, small_items)
  45. assert(len(large_items) == 1) // only enough bytes to make 1 x i64; two would need at least 8 bytes.
  46. ```
  47. */
  48. @(require_results)
  49. reinterpret :: proc "contextless" ($T: typeid/[]$U, s: []$V) -> []U {
  50. when size_of(U) == 0 || size_of(V) == 0 {
  51. return nil
  52. } else {
  53. bytes := to_bytes(s)
  54. n := len(bytes) / size_of(U)
  55. return ([^]U)(raw_data(bytes))[:n]
  56. }
  57. }
  58. swap :: proc(array: $T/[]$E, a, b: int) {
  59. when size_of(E) > 8 {
  60. ptr_swap_non_overlapping(&array[a], &array[b], size_of(E))
  61. } else {
  62. array[a], array[b] = array[b], array[a]
  63. }
  64. }
  65. swap_between :: proc(a, b: $T/[]$E) {
  66. n := builtin.min(len(a), len(b))
  67. if n >= 0 {
  68. ptr_swap_overlapping(&a[0], &b[0], size_of(E)*n)
  69. }
  70. }
  71. reverse :: proc(array: $T/[]$E) {
  72. n := len(array)/2
  73. for i in 0..<n {
  74. swap(array, i, len(array)-i-1)
  75. }
  76. }
  77. @(require_results)
  78. contains :: proc(array: $T/[]$E, value: E) -> bool where intrinsics.type_is_comparable(E) {
  79. _, found := linear_search(array, value)
  80. return found
  81. }
  82. @(require_results)
  83. linear_search :: proc(array: $A/[]$T, key: T) -> (index: int, found: bool)
  84. where intrinsics.type_is_comparable(T) #no_bounds_check {
  85. for x, i in array {
  86. if x == key {
  87. return i, true
  88. }
  89. }
  90. return -1, false
  91. }
  92. @(require_results)
  93. linear_search_proc :: proc(array: $A/[]$T, f: proc(T) -> bool) -> (index: int, found: bool) #no_bounds_check {
  94. for x, i in array {
  95. if f(x) {
  96. return i, true
  97. }
  98. }
  99. return -1, false
  100. }
  101. /*
  102. Binary search searches the given slice for the given element.
  103. If the slice is not sorted, the returned index is unspecified and meaningless.
  104. If the value is found then the returned int is the index of the matching element.
  105. If there are multiple matches, then any one of the matches could be returned.
  106. If the value is not found then the returned int is the index where a matching
  107. element could be inserted while maintaining sorted order.
  108. # Examples
  109. Looks up a series of four elements. The first is found, with a
  110. uniquely determined position; the second and third are not
  111. found; the fourth could match any position in `[1, 4]`.
  112. ```
  113. index: int
  114. found: bool
  115. s := []i32{0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55}
  116. index, found = slice.binary_search(s, 13)
  117. assert(index == 9 && found == true)
  118. index, found = slice.binary_search(s, 4)
  119. assert(index == 7 && found == false)
  120. index, found = slice.binary_search(s, 100)
  121. assert(index == 13 && found == false)
  122. index, found = slice.binary_search(s, 1)
  123. assert(index >= 1 && index <= 4 && found == true)
  124. ```
  125. For slices of more complex types see: binary_search_by
  126. */
  127. @(require_results)
  128. binary_search :: proc(array: $A/[]$T, key: T) -> (index: int, found: bool)
  129. where intrinsics.type_is_ordered(T) #no_bounds_check
  130. {
  131. // I would like to use binary_search_by(array, key, cmp) here, but it doesn't like it:
  132. // Cannot assign value 'cmp' of type 'proc($E, $E) -> Ordering' to 'proc(i32, i32) -> Ordering' in argument
  133. return binary_search_by(array, key, proc(key: T, element: T) -> Ordering {
  134. switch {
  135. case element < key: return .Less
  136. case element > key: return .Greater
  137. case: return .Equal
  138. }
  139. })
  140. }
  141. @(require_results)
  142. binary_search_by :: proc(array: $A/[]$T, key: T, f: proc(T, T) -> Ordering) -> (index: int, found: bool)
  143. where intrinsics.type_is_ordered(T) #no_bounds_check
  144. {
  145. // INVARIANTS:
  146. // - 0 <= left <= (left + size = right) <= len(array)
  147. // - f returns .Less for everything in array[:left]
  148. // - f returns .Greater for everything in array[right:]
  149. size := len(array)
  150. left := 0
  151. right := size
  152. for left < right {
  153. mid := left + size / 2
  154. // Steps to verify this is in-bounds:
  155. // 1. We note that `size` is strictly positive due to the loop condition
  156. // 2. Therefore `size/2 < size`
  157. // 3. Adding `left` to both sides yields `(left + size/2) < (left + size)`
  158. // 4. We know from the invariant that `left + size <= len(array)`
  159. // 5. Therefore `left + size/2 < self.len()`
  160. cmp := f(key, array[mid])
  161. left = mid + 1 if cmp == .Less else left
  162. right = mid if cmp == .Greater else right
  163. switch cmp {
  164. case .Equal: return mid, true
  165. case .Less: left = mid + 1
  166. case .Greater: right = mid
  167. }
  168. size = right - left
  169. }
  170. return left, false
  171. }
  172. @(require_results)
  173. equal :: proc(a, b: $T/[]$E) -> bool where intrinsics.type_is_comparable(E) {
  174. if len(a) != len(b) {
  175. return false
  176. }
  177. when intrinsics.type_is_simple_compare(E) {
  178. return runtime.memory_compare(raw_data(a), raw_data(b), len(a)*size_of(E)) == 0
  179. } else {
  180. for i in 0..<len(a) {
  181. if a[i] != b[i] {
  182. return false
  183. }
  184. }
  185. return true
  186. }
  187. }
  188. @(require_results)
  189. simple_equal :: proc(a, b: $T/[]$E) -> bool where intrinsics.type_is_simple_compare(E) {
  190. if len(a) != len(b) {
  191. return false
  192. }
  193. return runtime.memory_compare(raw_data(a), raw_data(b), len(a)*size_of(E)) == 0
  194. }
  195. /*
  196. return the prefix length common between slices `a` and `b`.
  197. slice.prefix_length([]u8{1, 2, 3, 4}, []u8{1}) -> 1
  198. slice.prefix_length([]u8{1, 2, 3, 4}, []u8{1, 2, 3}) -> 3
  199. slice.prefix_length([]u8{1, 2, 3, 4}, []u8{2, 3, 4}) -> 0
  200. */
  201. @(require_results)
  202. prefix_length :: proc(a, b: $T/[]$E) -> (n: int) where intrinsics.type_is_comparable(E) {
  203. _len := builtin.min(len(a), len(b))
  204. #no_bounds_check for n < _len && a[n] == b[n] {
  205. n += 1
  206. }
  207. return
  208. }
  209. @(require_results)
  210. has_prefix :: proc(array: $T/[]$E, needle: E) -> bool where intrinsics.type_is_comparable(E) {
  211. n := len(needle)
  212. if len(array) >= n {
  213. return equal(array[:n], needle)
  214. }
  215. return false
  216. }
  217. @(require_results)
  218. has_suffix :: proc(array: $T/[]$E, needle: E) -> bool where intrinsics.type_is_comparable(E) {
  219. array := array
  220. m, n := len(array), len(needle)
  221. if m >= n {
  222. return equal(array[m-n:], needle)
  223. }
  224. return false
  225. }
  226. zero :: proc(array: $T/[]$E) #no_bounds_check {
  227. if len(array) > 0 {
  228. intrinsics.mem_zero(raw_data(array), size_of(E)*len(array))
  229. }
  230. }
  231. fill :: proc(array: $T/[]$E, value: E) #no_bounds_check {
  232. if len(array) <= 0 {
  233. return
  234. }
  235. array[0] = value
  236. for i := 1; i < len(array); i *= 2 {
  237. copy(array[i:], array[:i])
  238. }
  239. }
  240. rotate_left :: proc(array: $T/[]$E, mid: int) {
  241. n := len(array)
  242. m := mid %% n
  243. k := n - m
  244. // FIXME: (ap29600) this cast is a temporary fix for the compiler not matching
  245. // [^T] with $P/^$T
  246. p := cast(^E)raw_data(array)
  247. ptr_rotate(m, ptr_add(p, m), k)
  248. }
  249. rotate_right :: proc(array: $T/[]$E, k: int) {
  250. rotate_left(array, -k)
  251. }
  252. swap_with_slice :: proc(a, b: $T/[]$E, loc := #caller_location) {
  253. assert(len(a) == len(b), "miss matching slice lengths", loc)
  254. ptr_swap_non_overlapping(raw_data(a), raw_data(b), len(a)*size_of(E))
  255. }
  256. @(require_results)
  257. concatenate :: proc(a: []$T/[]$E, allocator := context.allocator) -> (res: T, err: runtime.Allocator_Error) #optional_allocator_error {
  258. if len(a) == 0 {
  259. return
  260. }
  261. n := 0
  262. for s in a {
  263. n += len(s)
  264. }
  265. res = make(T, n, allocator) or_return
  266. i := 0
  267. for s in a {
  268. i += copy(res[i:], s)
  269. }
  270. return
  271. }
  272. // copies a slice into a new slice
  273. @(require_results)
  274. clone :: proc(a: $T/[]$E, allocator := context.allocator, loc := #caller_location) -> ([]E, runtime.Allocator_Error) #optional_allocator_error {
  275. d, err := make([]E, len(a), allocator, loc)
  276. copy(d[:], a)
  277. return d, err
  278. }
  279. // copies slice into a new dynamic array
  280. clone_to_dynamic :: proc(a: $T/[]$E, allocator := context.allocator, loc := #caller_location) -> ([dynamic]E, runtime.Allocator_Error) #optional_allocator_error {
  281. d, err := make([dynamic]E, len(a), allocator, loc)
  282. copy(d[:], a)
  283. return d, err
  284. }
  285. to_dynamic :: clone_to_dynamic
  286. // Converts slice into a dynamic array without cloning or allocating memory
  287. @(require_results)
  288. into_dynamic :: proc(a: $T/[]$E) -> [dynamic]E {
  289. s := transmute(runtime.Raw_Slice)a
  290. d := runtime.Raw_Dynamic_Array{
  291. data = s.data,
  292. len = 0,
  293. cap = s.len,
  294. allocator = runtime.nil_allocator(),
  295. }
  296. return transmute([dynamic]E)d
  297. }
  298. @(require_results)
  299. length :: proc(a: $T/[]$E) -> int {
  300. return len(a)
  301. }
  302. @(require_results)
  303. is_empty :: proc(a: $T/[]$E) -> bool {
  304. return len(a) == 0
  305. }
  306. @(require_results)
  307. split_at :: proc(array: $T/[]$E, index: int) -> (a, b: T) {
  308. return array[:index], array[index:]
  309. }
  310. @(require_results)
  311. split_first :: proc(array: $T/[]$E) -> (first: E, rest: T) {
  312. return array[0], array[1:]
  313. }
  314. @(require_results)
  315. split_last :: proc(array: $T/[]$E) -> (rest: T, last: E) {
  316. n := len(array)-1
  317. return array[:n], array[n]
  318. }
  319. @(require_results)
  320. first :: proc(array: $T/[]$E) -> E {
  321. return array[0]
  322. }
  323. @(require_results)
  324. last :: proc(array: $T/[]$E) -> E {
  325. return array[len(array)-1]
  326. }
  327. @(require_results)
  328. first_ptr :: proc(array: $T/[]$E) -> ^E {
  329. if len(array) != 0 {
  330. return &array[0]
  331. }
  332. return nil
  333. }
  334. @(require_results)
  335. last_ptr :: proc(array: $T/[]$E) -> ^E {
  336. if len(array) != 0 {
  337. return &array[len(array)-1]
  338. }
  339. return nil
  340. }
  341. @(require_results)
  342. get :: proc(array: $T/[]$E, index: int) -> (value: E, ok: bool) {
  343. if uint(index) < len(array) {
  344. value = array[index]
  345. ok = true
  346. }
  347. return
  348. }
  349. @(require_results)
  350. get_ptr :: proc(array: $T/[]$E, index: int) -> (value: ^E, ok: bool) {
  351. if uint(index) < len(array) {
  352. value = &array[index]
  353. ok = true
  354. }
  355. return
  356. }
  357. @(require_results)
  358. as_ptr :: proc(array: $T/[]$E) -> [^]E {
  359. return raw_data(array)
  360. }
  361. @(require_results)
  362. mapper :: proc(s: $S/[]$U, f: proc(U) -> $V, allocator := context.allocator) -> (r: []V, err: runtime.Allocator_Error) #optional_allocator_error {
  363. r = make([]V, len(s), allocator) or_return
  364. for v, i in s {
  365. r[i] = f(v)
  366. }
  367. return
  368. }
  369. @(require_results)
  370. reduce :: proc(s: $S/[]$U, initializer: $V, f: proc(V, U) -> V) -> V {
  371. r := initializer
  372. for v in s {
  373. r = f(r, v)
  374. }
  375. return r
  376. }
  377. @(require_results)
  378. filter :: proc(s: $S/[]$U, f: proc(U) -> bool, allocator := context.allocator) -> S {
  379. r := make([dynamic]U, 0, 0, allocator)
  380. for v in s {
  381. if f(v) {
  382. append(&r, v)
  383. }
  384. }
  385. return r[:]
  386. }
  387. @(require_results)
  388. scanner :: proc (s: $S/[]$U, initializer: $V, f: proc(V, U) -> V, allocator := context.allocator) -> (res: []V, err: runtime.Allocator_Error) #optional_allocator_error {
  389. if len(s) == 0 { return }
  390. res = make([]V, len(s), allocator) or_return
  391. p := as_ptr(s)
  392. q := as_ptr(res)
  393. r := initializer
  394. for l := len(s); l > 0; l -= 1 {
  395. r = f(r, p[0])
  396. q[0] = r
  397. p = p[1:]
  398. q = q[1:]
  399. }
  400. return
  401. }
  402. @(require_results)
  403. min :: proc(s: $S/[]$T) -> (res: T, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok {
  404. if len(s) != 0 {
  405. res = s[0]
  406. ok = true
  407. for v in s[1:] {
  408. res = builtin.min(res, v)
  409. }
  410. }
  411. return
  412. }
  413. @(require_results)
  414. max :: proc(s: $S/[]$T) -> (res: T, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok {
  415. if len(s) != 0 {
  416. res = s[0]
  417. ok = true
  418. for v in s[1:] {
  419. res = builtin.max(res, v)
  420. }
  421. }
  422. return
  423. }
  424. @(require_results)
  425. min_max :: proc(s: $S/[]$T) -> (min, max: T, ok: bool) where intrinsics.type_is_ordered(T) {
  426. if len(s) != 0 {
  427. min, max = s[0], s[0]
  428. ok = true
  429. for v in s[1:] {
  430. min = builtin.min(min, v)
  431. max = builtin.max(max, v)
  432. }
  433. }
  434. return
  435. }
  436. // Find the index of the (first) minimum element in a slice.
  437. @(require_results)
  438. min_index :: proc(s: $S/[]$T) -> (min_index: int, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok {
  439. if len(s) == 0 {
  440. return -1, false
  441. }
  442. min_index = 0
  443. min_value := s[0]
  444. for v, i in s[1:] {
  445. if v < min_value {
  446. min_value = v
  447. min_index = i+1
  448. }
  449. }
  450. return min_index, true
  451. }
  452. // Find the index of the (first) maximum element in a slice.
  453. @(require_results)
  454. max_index :: proc(s: $S/[]$T) -> (max_index: int, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok {
  455. if len(s) == 0 {
  456. return -1, false
  457. }
  458. max_index = 0
  459. max_value := s[0]
  460. for v, i in s[1:] {
  461. if v > max_value {
  462. max_value = v
  463. max_index = i+1
  464. }
  465. }
  466. return max_index, true
  467. }
  468. @(require_results)
  469. any_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) {
  470. for v in s {
  471. if v == value {
  472. return true
  473. }
  474. }
  475. return false
  476. }
  477. @(require_results)
  478. none_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) {
  479. for v in s {
  480. if v == value {
  481. return false
  482. }
  483. }
  484. return true
  485. }
  486. @(require_results)
  487. all_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) {
  488. if len(s) == 0 {
  489. return false
  490. }
  491. for v in s {
  492. if v != value {
  493. return false
  494. }
  495. }
  496. return true
  497. }
  498. @(require_results)
  499. any_of_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> bool {
  500. for v in s {
  501. if f(v) {
  502. return true
  503. }
  504. }
  505. return false
  506. }
  507. @(require_results)
  508. none_of_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> bool {
  509. for v in s {
  510. if f(v) {
  511. return false
  512. }
  513. }
  514. return true
  515. }
  516. @(require_results)
  517. all_of_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> bool {
  518. if len(s) == 0 {
  519. return false
  520. }
  521. for v in s {
  522. if !f(v) {
  523. return false
  524. }
  525. }
  526. return true
  527. }
  528. @(require_results)
  529. count :: proc(s: $S/[]$T, value: T) -> (n: int) where intrinsics.type_is_comparable(T) {
  530. for v in s {
  531. if v == value {
  532. n += 1
  533. }
  534. }
  535. return
  536. }
  537. @(require_results)
  538. count_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> (n: int) {
  539. for v in s {
  540. if f(v) {
  541. n += 1
  542. }
  543. }
  544. return
  545. }
  546. @(require_results)
  547. dot_product :: proc(a, b: $S/[]$T) -> (r: T, ok: bool)
  548. where intrinsics.type_is_numeric(T) {
  549. if len(a) != len(b) {
  550. return
  551. }
  552. #no_bounds_check for _, i in a {
  553. r += a[i] * b[i]
  554. }
  555. return r, true
  556. }
  557. // Convert a pointer to an enumerated array to a slice of the element type
  558. @(require_results)
  559. enumerated_array :: proc(ptr: ^$T) -> []intrinsics.type_elem_type(T)
  560. where intrinsics.type_is_enumerated_array(T) {
  561. return ([^]intrinsics.type_elem_type(T))(ptr)[:len(T)]
  562. }