slice.odin 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. package slice
  2. import "base:intrinsics"
  3. import "base:builtin"
  4. import "core:math/bits"
  5. import "base: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. return binary_search_by(array, key, cmp_proc(T))
  131. }
  132. /*
  133. Binary search searches the given slice for the given element.
  134. If the slice is not sorted, the returned index is unspecified and meaningless.
  135. If the value is found then the returned int is the index of the matching element.
  136. If there are multiple matches, then any one of the matches could be returned.
  137. If the value is not found then the returned int is the index where a matching
  138. element could be inserted while maintaining sorted order.
  139. The array elements and key may be different types. This allows the filter procedure
  140. to compare keys against a slice of structs, one struct value at a time.
  141. Returns:
  142. index: int
  143. found: bool
  144. */
  145. @(require_results)
  146. binary_search_by :: proc(array: $A/[]$T, key: $K, f: proc(T, K) -> Ordering) -> (index: int, found: bool) #no_bounds_check {
  147. n := len(array)
  148. left, right := 0, n
  149. for left < right {
  150. mid := int(uint(left+right) >> 1)
  151. if f(array[mid], key) == .Less {
  152. left = mid+1
  153. } else {
  154. // .Equal or .Greater
  155. right = mid
  156. }
  157. }
  158. return left, left < n && f(array[left], key) == .Equal
  159. }
  160. @(require_results)
  161. equal :: proc(a, b: $T/[]$E) -> bool where intrinsics.type_is_comparable(E) #no_bounds_check {
  162. if len(a) != len(b) {
  163. return false
  164. }
  165. when intrinsics.type_is_simple_compare(E) {
  166. return runtime.memory_compare(raw_data(a), raw_data(b), len(a)*size_of(E)) == 0
  167. } else {
  168. for i in 0..<len(a) {
  169. if a[i] != b[i] {
  170. return false
  171. }
  172. }
  173. return true
  174. }
  175. }
  176. @(require_results)
  177. simple_equal :: proc(a, b: $T/[]$E) -> bool where intrinsics.type_is_simple_compare(E) {
  178. if len(a) != len(b) {
  179. return false
  180. }
  181. return runtime.memory_compare(raw_data(a), raw_data(b), len(a)*size_of(E)) == 0
  182. }
  183. /*
  184. return the prefix length common between slices `a` and `b`.
  185. slice.prefix_length([]u8{1, 2, 3, 4}, []u8{1}) -> 1
  186. slice.prefix_length([]u8{1, 2, 3, 4}, []u8{1, 2, 3}) -> 3
  187. slice.prefix_length([]u8{1, 2, 3, 4}, []u8{2, 3, 4}) -> 0
  188. */
  189. @(require_results)
  190. prefix_length :: proc(a, b: $T/[]$E) -> (n: int) where intrinsics.type_is_comparable(E) {
  191. _len := builtin.min(len(a), len(b))
  192. #no_bounds_check for n < _len && a[n] == b[n] {
  193. n += 1
  194. }
  195. return
  196. }
  197. @(require_results)
  198. has_prefix :: proc(array: $T/[]$E, needle: T) -> bool where intrinsics.type_is_comparable(E) {
  199. n := len(needle)
  200. if len(array) >= n {
  201. return equal(array[:n], needle)
  202. }
  203. return false
  204. }
  205. @(require_results)
  206. has_suffix :: proc(array: $T/[]$E, needle: T) -> bool where intrinsics.type_is_comparable(E) {
  207. array := array
  208. m, n := len(array), len(needle)
  209. if m >= n {
  210. return equal(array[m-n:], needle)
  211. }
  212. return false
  213. }
  214. zero :: proc(array: $T/[]$E) #no_bounds_check {
  215. if len(array) > 0 {
  216. intrinsics.mem_zero(raw_data(array), size_of(E)*len(array))
  217. }
  218. }
  219. fill :: proc(array: $T/[]$E, value: E) #no_bounds_check {
  220. if len(array) <= 0 {
  221. return
  222. }
  223. array[0] = value
  224. for i := 1; i < len(array); i *= 2 {
  225. copy(array[i:], array[:i])
  226. }
  227. }
  228. rotate_left :: proc(array: $T/[]$E, mid: int) {
  229. n := len(array)
  230. m := mid %% n
  231. k := n - m
  232. // FIXME: (ap29600) this cast is a temporary fix for the compiler not matching
  233. // [^T] with $P/^$T
  234. p := cast(^E)raw_data(array)
  235. ptr_rotate(m, ptr_add(p, m), k)
  236. }
  237. rotate_right :: proc(array: $T/[]$E, k: int) {
  238. rotate_left(array, -k)
  239. }
  240. swap_with_slice :: proc(a, b: $T/[]$E, loc := #caller_location) {
  241. assert(len(a) == len(b), "miss matching slice lengths", loc)
  242. ptr_swap_non_overlapping(raw_data(a), raw_data(b), len(a)*size_of(E))
  243. }
  244. @(require_results)
  245. concatenate :: proc(a: []$T/[]$E, allocator := context.allocator) -> (res: T, err: runtime.Allocator_Error) #optional_allocator_error {
  246. if len(a) == 0 {
  247. return
  248. }
  249. n := 0
  250. for s in a {
  251. n += len(s)
  252. }
  253. res = make(T, n, allocator) or_return
  254. i := 0
  255. for s in a {
  256. i += copy(res[i:], s)
  257. }
  258. return
  259. }
  260. // copies a slice into a new slice
  261. @(require_results)
  262. clone :: proc(a: $T/[]$E, allocator := context.allocator, loc := #caller_location) -> ([]E, runtime.Allocator_Error) #optional_allocator_error {
  263. d, err := make([]E, len(a), allocator, loc)
  264. copy(d[:], a)
  265. return d, err
  266. }
  267. // copies slice into a new dynamic array
  268. clone_to_dynamic :: proc(a: $T/[]$E, allocator := context.allocator, loc := #caller_location) -> ([dynamic]E, runtime.Allocator_Error) #optional_allocator_error {
  269. d, err := make([dynamic]E, len(a), allocator, loc)
  270. copy(d[:], a)
  271. return d, err
  272. }
  273. to_dynamic :: clone_to_dynamic
  274. // Converts slice into a dynamic array without cloning or allocating memory
  275. @(require_results)
  276. into_dynamic :: proc(a: $T/[]$E) -> [dynamic]E {
  277. s := transmute(runtime.Raw_Slice)a
  278. d := runtime.Raw_Dynamic_Array{
  279. data = s.data,
  280. len = 0,
  281. cap = s.len,
  282. allocator = runtime.nil_allocator(),
  283. }
  284. return transmute([dynamic]E)d
  285. }
  286. @(require_results)
  287. length :: proc(a: $T/[]$E) -> int {
  288. return len(a)
  289. }
  290. @(require_results)
  291. is_empty :: proc(a: $T/[]$E) -> bool {
  292. return len(a) == 0
  293. }
  294. @(require_results)
  295. split_at :: proc(array: $T/[]$E, index: int) -> (a, b: T) {
  296. return array[:index], array[index:]
  297. }
  298. @(require_results)
  299. split_first :: proc(array: $T/[]$E) -> (first: E, rest: T) {
  300. return array[0], array[1:]
  301. }
  302. @(require_results)
  303. split_last :: proc(array: $T/[]$E) -> (rest: T, last: E) {
  304. n := len(array)-1
  305. return array[:n], array[n]
  306. }
  307. @(require_results)
  308. first :: proc(array: $T/[]$E) -> E {
  309. return array[0]
  310. }
  311. @(require_results)
  312. last :: proc(array: $T/[]$E) -> E {
  313. return array[len(array)-1]
  314. }
  315. @(require_results)
  316. first_ptr :: proc(array: $T/[]$E) -> ^E {
  317. if len(array) != 0 {
  318. return &array[0]
  319. }
  320. return nil
  321. }
  322. @(require_results)
  323. last_ptr :: proc(array: $T/[]$E) -> ^E {
  324. if len(array) != 0 {
  325. return &array[len(array)-1]
  326. }
  327. return nil
  328. }
  329. @(require_results)
  330. get :: proc(array: $T/[]$E, index: int) -> (value: E, ok: bool) {
  331. if uint(index) < len(array) {
  332. value = array[index]
  333. ok = true
  334. }
  335. return
  336. }
  337. @(require_results)
  338. get_ptr :: proc(array: $T/[]$E, index: int) -> (value: ^E, ok: bool) {
  339. if uint(index) < len(array) {
  340. value = &array[index]
  341. ok = true
  342. }
  343. return
  344. }
  345. @(require_results)
  346. as_ptr :: proc(array: $T/[]$E) -> [^]E {
  347. return raw_data(array)
  348. }
  349. @(require_results)
  350. mapper :: proc(s: $S/[]$U, f: proc(U) -> $V, allocator := context.allocator) -> (r: []V, err: runtime.Allocator_Error) #optional_allocator_error {
  351. r = make([]V, len(s), allocator) or_return
  352. for v, i in s {
  353. r[i] = f(v)
  354. }
  355. return
  356. }
  357. @(require_results)
  358. reduce :: proc(s: $S/[]$U, initializer: $V, f: proc(V, U) -> V) -> V {
  359. r := initializer
  360. for v in s {
  361. r = f(r, v)
  362. }
  363. return r
  364. }
  365. @(require_results)
  366. reduce_reverse :: proc(s: $S/[]$U, initializer: $V, f: proc(V, U) -> V) -> V {
  367. r := initializer
  368. for i := len(s)-1; i >= 0; i -= 1 {
  369. #no_bounds_check r = f(r, s[i])
  370. }
  371. return r
  372. }
  373. @(require_results)
  374. filter :: proc(s: $S/[]$U, f: proc(U) -> bool, allocator := context.allocator) -> (res: S, err: runtime.Allocator_Error) #optional_allocator_error {
  375. r := make([dynamic]U, 0, 0, allocator) or_return
  376. for v in s {
  377. if f(v) {
  378. append(&r, v)
  379. }
  380. }
  381. return r[:], nil
  382. }
  383. @(require_results)
  384. filter_reverse :: proc(s: $S/[]$U, f: proc(U) -> bool, allocator := context.allocator) -> (res: S, err: runtime.Allocator_Error) #optional_allocator_error {
  385. r := make([dynamic]U, 0, 0, allocator) or_return
  386. for i := len(s)-1; i >= 0; i -= 1 {
  387. #no_bounds_check v := s[i]
  388. if f(v) {
  389. append(&r, v)
  390. }
  391. }
  392. return r[:], nil
  393. }
  394. @(require_results)
  395. scanner :: proc (s: $S/[]$U, initializer: $V, f: proc(V, U) -> V, allocator := context.allocator) -> (res: []V, err: runtime.Allocator_Error) #optional_allocator_error {
  396. if len(s) == 0 { return }
  397. res = make([]V, len(s), allocator) or_return
  398. p := as_ptr(s)
  399. q := as_ptr(res)
  400. r := initializer
  401. for l := len(s); l > 0; l -= 1 {
  402. r = f(r, p[0])
  403. q[0] = r
  404. p = p[1:]
  405. q = q[1:]
  406. }
  407. return
  408. }
  409. @(require_results)
  410. repeat :: proc(s: $S/[]$U, count: int, allocator := context.allocator) -> (b: S, err: runtime.Allocator_Error) #optional_allocator_error {
  411. if count < 0 {
  412. panic("slice: negative repeat count")
  413. } else if count > 0 && (len(s)*count)/count != len(s) {
  414. panic("slice: repeat count will cause an overflow")
  415. }
  416. b = make(S, len(s)*count, allocator) or_return
  417. i := copy(b, s)
  418. for i < len(b) { // 2^N trick to reduce the need to copy
  419. copy(b[i:], b[:i])
  420. i *= 2
  421. }
  422. return
  423. }
  424. // 'unique' replaces consecutive runs of equal elements with a single copy.
  425. // The procedures modifies the slice in-place and returns the modified slice.
  426. @(require_results)
  427. unique :: proc(s: $S/[]$T) -> S where intrinsics.type_is_comparable(T) #no_bounds_check {
  428. if len(s) < 2 {
  429. return s
  430. }
  431. i := 1
  432. for j in 1..<len(s) {
  433. if s[j] != s[j-1] {
  434. if i != j {
  435. s[i] = s[j]
  436. }
  437. i += 1
  438. }
  439. }
  440. return s[:i]
  441. }
  442. // 'unique_proc' replaces consecutive runs of equal elements with a single copy using a comparison procedure
  443. // The procedures modifies the slice in-place and returns the modified slice.
  444. @(require_results)
  445. unique_proc :: proc(s: $S/[]$T, eq: proc(T, T) -> bool) -> S #no_bounds_check {
  446. if len(s) < 2 {
  447. return s
  448. }
  449. i := 1
  450. for j in 1..<len(s) {
  451. if !eq(s[j], s[j-1]) {
  452. if i != j {
  453. s[i] = s[j]
  454. }
  455. i += 1
  456. }
  457. }
  458. return s[:i]
  459. }
  460. @(require_results)
  461. min :: proc(s: $S/[]$T) -> (res: T, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok {
  462. if len(s) != 0 {
  463. res = s[0]
  464. ok = true
  465. for v in s[1:] {
  466. res = builtin.min(res, v)
  467. }
  468. }
  469. return
  470. }
  471. @(require_results)
  472. max :: proc(s: $S/[]$T) -> (res: T, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok {
  473. if len(s) != 0 {
  474. res = s[0]
  475. ok = true
  476. for v in s[1:] {
  477. res = builtin.max(res, v)
  478. }
  479. }
  480. return
  481. }
  482. @(require_results)
  483. min_max :: proc(s: $S/[]$T) -> (min, max: T, ok: bool) where intrinsics.type_is_ordered(T) {
  484. if len(s) != 0 {
  485. min, max = s[0], s[0]
  486. ok = true
  487. for v in s[1:] {
  488. min = builtin.min(min, v)
  489. max = builtin.max(max, v)
  490. }
  491. }
  492. return
  493. }
  494. // Find the index of the (first) minimum element in a slice.
  495. @(require_results)
  496. min_index :: proc(s: $S/[]$T) -> (min_index: int, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok {
  497. if len(s) == 0 {
  498. return -1, false
  499. }
  500. min_index = 0
  501. min_value := s[0]
  502. for v, i in s[1:] {
  503. if v < min_value {
  504. min_value = v
  505. min_index = i+1
  506. }
  507. }
  508. return min_index, true
  509. }
  510. // Find the index of the (first) maximum element in a slice.
  511. @(require_results)
  512. max_index :: proc(s: $S/[]$T) -> (max_index: int, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok {
  513. if len(s) == 0 {
  514. return -1, false
  515. }
  516. max_index = 0
  517. max_value := s[0]
  518. for v, i in s[1:] {
  519. if v > max_value {
  520. max_value = v
  521. max_index = i+1
  522. }
  523. }
  524. return max_index, true
  525. }
  526. @(require_results)
  527. any_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) {
  528. for v in s {
  529. if v == value {
  530. return true
  531. }
  532. }
  533. return false
  534. }
  535. @(require_results)
  536. none_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) {
  537. for v in s {
  538. if v == value {
  539. return false
  540. }
  541. }
  542. return true
  543. }
  544. @(require_results)
  545. all_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) {
  546. if len(s) == 0 {
  547. return false
  548. }
  549. for v in s {
  550. if v != value {
  551. return false
  552. }
  553. }
  554. return true
  555. }
  556. @(require_results)
  557. any_of_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> bool {
  558. for v in s {
  559. if f(v) {
  560. return true
  561. }
  562. }
  563. return false
  564. }
  565. @(require_results)
  566. none_of_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> bool {
  567. for v in s {
  568. if f(v) {
  569. return false
  570. }
  571. }
  572. return true
  573. }
  574. @(require_results)
  575. all_of_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> bool {
  576. if len(s) == 0 {
  577. return false
  578. }
  579. for v in s {
  580. if !f(v) {
  581. return false
  582. }
  583. }
  584. return true
  585. }
  586. @(require_results)
  587. count :: proc(s: $S/[]$T, value: T) -> (n: int) where intrinsics.type_is_comparable(T) {
  588. for v in s {
  589. if v == value {
  590. n += 1
  591. }
  592. }
  593. return
  594. }
  595. @(require_results)
  596. count_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> (n: int) {
  597. for v in s {
  598. if f(v) {
  599. n += 1
  600. }
  601. }
  602. return
  603. }
  604. @(require_results)
  605. dot_product :: proc(a, b: $S/[]$T) -> (r: T, ok: bool)
  606. where intrinsics.type_is_numeric(T) {
  607. if len(a) != len(b) {
  608. return
  609. }
  610. #no_bounds_check for _, i in a {
  611. r += a[i] * b[i]
  612. }
  613. return r, true
  614. }
  615. // Convert a pointer to an enumerated array to a slice of the element type
  616. @(require_results)
  617. enumerated_array :: proc(ptr: ^$T) -> []intrinsics.type_elem_type(T)
  618. where intrinsics.type_is_enumerated_array(T) {
  619. return ([^]intrinsics.type_elem_type(T))(ptr)[:len(T)]
  620. }
  621. // Turn a `[]E` into `bit_set[E]`
  622. // e.g.:
  623. // bs := slice.enum_slice_to_bitset(my_flag_slice, rl.ConfigFlags)
  624. @(require_results)
  625. enum_slice_to_bitset :: proc(enums: []$E, $T: typeid/bit_set[E]) -> (bits: T) where intrinsics.type_is_enum(E), intrinsics.type_bit_set_elem_type(T) == E {
  626. for v in enums {
  627. bits += {v}
  628. }
  629. return
  630. }
  631. // Turn a `bit_set[E]` into a `[]E`
  632. // e.g.:
  633. // sl := slice.bitset_to_enum_slice(flag_buf[:], bs)
  634. @(require_results)
  635. bitset_to_enum_slice_with_buffer :: proc(buf: []$E, bs: $T) -> (slice: []E) where intrinsics.type_is_enum(E), intrinsics.type_bit_set_elem_type(T) == E {
  636. count := 0
  637. for v in bs {
  638. buf[count] = v
  639. count += 1
  640. }
  641. return buf[:count]
  642. }
  643. // Turn a `bit_set[E]` into a `[]E`, allocates
  644. // e.g.:
  645. // sl := slice.bitset_to_enum_slice(bs)
  646. @(require_results)
  647. bitset_to_enum_slice_with_make :: proc(bs: $T, $E: typeid, allocator := context.allocator) -> (slice: []E) where intrinsics.type_is_enum(E), intrinsics.type_bit_set_elem_type(T) == E {
  648. ones := intrinsics.count_ones(transmute(E)bs)
  649. buf := make([]E, int(ones), allocator)
  650. return bitset_to_enum_slice(buf, bs)
  651. }
  652. bitset_to_enum_slice :: proc{bitset_to_enum_slice_with_make, bitset_to_enum_slice_with_buffer}