slice.odin 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  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. has_prefix :: proc(array: $T/[]$E, needle: E) -> bool where intrinsics.type_is_comparable(E) {
  147. n := len(needle)
  148. if len(array) >= n {
  149. return equal(array[:n], needle)
  150. }
  151. return false
  152. }
  153. has_suffix :: proc(array: $T/[]$E, needle: E) -> bool where intrinsics.type_is_comparable(E) {
  154. array := array
  155. m, n := len(array), len(needle)
  156. if m >= n {
  157. return equal(array[m-n:], needle)
  158. }
  159. return false
  160. }
  161. fill :: proc(array: $T/[]$E, value: E) #no_bounds_check {
  162. if len(array) <= 0 {
  163. return
  164. }
  165. array[0] = value
  166. for i := 1; i < len(array); i *= 2 {
  167. copy(array[i:], array[:i])
  168. }
  169. }
  170. rotate_left :: proc(array: $T/[]$E, mid: int) {
  171. n := len(array)
  172. m := mid %% n
  173. k := n - m
  174. p := raw_data(array)
  175. ptr_rotate(mid, ptr_add(p, mid), k)
  176. }
  177. rotate_right :: proc(array: $T/[]$E, k: int) {
  178. rotate_left(array, -k)
  179. }
  180. swap_with_slice :: proc(a, b: $T/[]$E, loc := #caller_location) {
  181. assert(len(a) == len(b), "miss matching slice lengths", loc)
  182. ptr_swap_non_overlapping(raw_data(a), raw_data(b), len(a)*size_of(E))
  183. }
  184. concatenate :: proc(a: []$T/[]$E, allocator := context.allocator) -> (res: T) {
  185. if len(a) == 0 {
  186. return
  187. }
  188. n := 0
  189. for s in a {
  190. n += len(s)
  191. }
  192. res = make(T, n, allocator)
  193. i := 0
  194. for s in a {
  195. i += copy(res[i:], s)
  196. }
  197. return
  198. }
  199. // copies a slice into a new slice
  200. clone :: proc(a: $T/[]$E, allocator := context.allocator) -> []E {
  201. d := make([]E, len(a), allocator)
  202. copy(d[:], a)
  203. return d
  204. }
  205. // copies slice into a new dynamic array
  206. clone_to_dynamic :: proc(a: $T/[]$E, allocator := context.allocator) -> [dynamic]E {
  207. d := make([dynamic]E, len(a), allocator)
  208. copy(d[:], a)
  209. return d
  210. }
  211. to_dynamic :: clone_to_dynamic
  212. // Converts slice into a dynamic array without cloning or allocating memory
  213. into_dynamic :: proc(a: $T/[]$E) -> [dynamic]E {
  214. s := transmute(mem.Raw_Slice)a
  215. d := mem.Raw_Dynamic_Array{
  216. data = s.data,
  217. len = 0,
  218. cap = s.len,
  219. allocator = mem.nil_allocator(),
  220. }
  221. return transmute([dynamic]E)d
  222. }
  223. length :: proc(a: $T/[]$E) -> int {
  224. return len(a)
  225. }
  226. is_empty :: proc(a: $T/[]$E) -> bool {
  227. return len(a) == 0
  228. }
  229. split_at :: proc(array: $T/[]$E, index: int) -> (a, b: T) {
  230. return array[:index], array[index:]
  231. }
  232. split_first :: proc(array: $T/[]$E) -> (first: E, rest: T) {
  233. return array[0], array[1:]
  234. }
  235. split_last :: proc(array: $T/[]$E) -> (rest: T, last: E) {
  236. n := len(array)-1
  237. return array[:n], array[n]
  238. }
  239. first :: proc(array: $T/[]$E) -> E {
  240. return array[0]
  241. }
  242. last :: proc(array: $T/[]$E) -> E {
  243. return array[len(array)-1]
  244. }
  245. first_ptr :: proc(array: $T/[]$E) -> ^E {
  246. if len(array) != 0 {
  247. return &array[0]
  248. }
  249. return nil
  250. }
  251. last_ptr :: proc(array: $T/[]$E) -> ^E {
  252. if len(array) != 0 {
  253. return &array[len(array)-1]
  254. }
  255. return nil
  256. }
  257. get :: proc(array: $T/[]$E, index: int) -> (value: E, ok: bool) {
  258. if 0 <= index && index < len(array) {
  259. value = array[index]
  260. ok = true
  261. }
  262. return
  263. }
  264. get_ptr :: proc(array: $T/[]$E, index: int) -> (value: ^E, ok: bool) {
  265. if 0 <= index && index < len(array) {
  266. value = &array[index]
  267. ok = true
  268. }
  269. return
  270. }
  271. as_ptr :: proc(array: $T/[]$E) -> [^]E {
  272. return raw_data(array)
  273. }
  274. mapper :: proc(s: $S/[]$U, f: proc(U) -> $V, allocator := context.allocator) -> []V {
  275. r := make([]V, len(s), allocator)
  276. for v, i in s {
  277. r[i] = f(v)
  278. }
  279. return r
  280. }
  281. reduce :: proc(s: $S/[]$U, initializer: $V, f: proc(V, U) -> V) -> V {
  282. r := initializer
  283. for v in s {
  284. r = f(r, v)
  285. }
  286. return r
  287. }
  288. filter :: proc(s: $S/[]$U, f: proc(U) -> bool, allocator := context.allocator) -> S {
  289. r := make([dynamic]U, 0, 0, allocator)
  290. for v in s {
  291. if f(v) {
  292. append(&r, v)
  293. }
  294. }
  295. return r[:]
  296. }
  297. scanner :: proc (s: $S/[]$U, initializer: $V, f: proc(V, U) -> V, allocator := context.allocator) -> []V {
  298. if len(s) == 0 { return {} }
  299. res := make([]V, len(s), allocator)
  300. p := as_ptr(s)
  301. q := as_ptr(res)
  302. r := initializer
  303. for l := len(s); l > 0; l -= 1 {
  304. r = f(r, p[0])
  305. q[0] = r
  306. p = p[1:]
  307. q = q[1:]
  308. }
  309. return res
  310. }
  311. min :: proc(s: $S/[]$T) -> (res: T, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok {
  312. if len(s) != 0 {
  313. res = s[0]
  314. ok = true
  315. for v in s[1:] {
  316. res = builtin.min(res, v)
  317. }
  318. }
  319. return
  320. }
  321. max :: proc(s: $S/[]$T) -> (res: T, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok {
  322. if len(s) != 0 {
  323. res = s[0]
  324. ok = true
  325. for v in s[1:] {
  326. res = builtin.max(res, v)
  327. }
  328. }
  329. return
  330. }
  331. min_max :: proc(s: $S/[]$T) -> (min, max: T, ok: bool) where intrinsics.type_is_ordered(T) {
  332. if len(s) != 0 {
  333. min, max = s[0], s[0]
  334. ok = true
  335. for v in s[1:] {
  336. min = builtin.min(min, v)
  337. max = builtin.max(max, v)
  338. }
  339. }
  340. return
  341. }
  342. any_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) {
  343. for v in s {
  344. if v == value {
  345. return true
  346. }
  347. }
  348. return false
  349. }
  350. none_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) {
  351. for v in s {
  352. if v == value {
  353. return false
  354. }
  355. }
  356. return true
  357. }
  358. all_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) {
  359. if len(s) == 0 {
  360. return false
  361. }
  362. for v in s {
  363. if v != value {
  364. return false
  365. }
  366. }
  367. return true
  368. }
  369. any_of_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> bool {
  370. for v in s {
  371. if f(v) {
  372. return true
  373. }
  374. }
  375. return false
  376. }
  377. none_of_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> bool {
  378. for v in s {
  379. if f(v) {
  380. return false
  381. }
  382. }
  383. return true
  384. }
  385. all_of_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> bool {
  386. if len(s) == 0 {
  387. return false
  388. }
  389. for v in s {
  390. if !f(v) {
  391. return false
  392. }
  393. }
  394. return true
  395. }
  396. count :: proc(s: $S/[]$T, value: T) -> (n: int) where intrinsics.type_is_comparable(T) {
  397. for v in s {
  398. if v == value {
  399. n += 1
  400. }
  401. }
  402. return
  403. }
  404. count_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> (n: int) {
  405. for v in s {
  406. if f(v) {
  407. n += 1
  408. }
  409. }
  410. return
  411. }
  412. dot_product :: proc(a, b: $S/[]$T) -> (r: T, ok: bool)
  413. where intrinsics.type_is_numeric(T) {
  414. if len(a) != len(b) {
  415. return
  416. }
  417. #no_bounds_check for _, i in a {
  418. r += a[i] * b[i]
  419. }
  420. return r, true
  421. }