slice.odin 10 KB

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