rand.odin 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. /*
  2. Package core:math/rand implements various random number generators
  3. */
  4. package rand
  5. import "base:intrinsics"
  6. import "core:crypto"
  7. import "core:math"
  8. import "core:mem"
  9. Rand :: struct {
  10. state: u64,
  11. inc: u64,
  12. is_system: bool,
  13. }
  14. @(private)
  15. global_rand := create(u64(intrinsics.read_cycle_counter()))
  16. /*
  17. Sets the seed used by the global random number generator.
  18. Inputs:
  19. - seed: The seed value
  20. Example:
  21. import "core:math/rand"
  22. import "core:fmt"
  23. set_global_seed_example :: proc() {
  24. rand.set_global_seed(1)
  25. fmt.println(rand.uint64())
  26. }
  27. Possible Output:
  28. 10
  29. */
  30. set_global_seed :: proc(seed: u64) {
  31. init(&global_rand, seed)
  32. }
  33. /*
  34. Creates a new random number generator.
  35. Inputs:
  36. - seed: The seed value to create the random number generator with
  37. Returns:
  38. - res: The created random number generator
  39. Example:
  40. import "core:math/rand"
  41. import "core:fmt"
  42. create_example :: proc() {
  43. my_rand := rand.create(1)
  44. fmt.println(rand.uint64(&my_rand))
  45. }
  46. Possible Output:
  47. 10
  48. */
  49. @(require_results)
  50. create :: proc(seed: u64) -> (res: Rand) {
  51. r: Rand
  52. init(&r, seed)
  53. return r
  54. }
  55. /*
  56. Initialises a random number generator.
  57. Inputs:
  58. - r: The random number generator to initialise
  59. - seed: The seed value to initialise this random number generator
  60. Example:
  61. import "core:math/rand"
  62. import "core:fmt"
  63. init_example :: proc() {
  64. my_rand: rand.Rand
  65. rand.init(&my_rand, 1)
  66. fmt.println(rand.uint64(&my_rand))
  67. }
  68. Possible Output:
  69. 10
  70. */
  71. init :: proc(r: ^Rand, seed: u64) {
  72. r.state = 0
  73. r.inc = (seed << 1) | 1
  74. _random_u64(r)
  75. r.state += seed
  76. _random_u64(r)
  77. }
  78. /*
  79. Initialises a random number generator to use the system random number generator.
  80. The system random number generator is platform specific, and not supported
  81. on all targets.
  82. Inputs:
  83. - r: The random number generator to use the system random number generator
  84. WARNING: Panics if the system random number generator is not supported.
  85. Support can be determined via the `core:crypto.HAS_RAND_BYTES` constant.
  86. Example:
  87. import "core:crypto"
  88. import "core:math/rand"
  89. import "core:fmt"
  90. init_as_system_example :: proc() {
  91. my_rand: rand.Rand
  92. switch crypto.HAS_RAND_BYTES {
  93. case true:
  94. rand.init_as_system(&my_rand)
  95. fmt.println(rand.uint64(&my_rand))
  96. case false:
  97. fmt.println("system random not supported!")
  98. }
  99. }
  100. Possible Output:
  101. 10
  102. */
  103. init_as_system :: proc(r: ^Rand) {
  104. if !crypto.HAS_RAND_BYTES {
  105. panic(#procedure + " is not supported on this platform yet")
  106. }
  107. r.state = 0
  108. r.inc = 0
  109. r.is_system = true
  110. }
  111. @(private)
  112. _random_u64 :: proc(r: ^Rand) -> u64 {
  113. r := r
  114. switch {
  115. case r == nil:
  116. r = &global_rand
  117. case r.is_system:
  118. value: u64
  119. crypto.rand_bytes((cast([^]u8)&value)[:size_of(u64)])
  120. return value
  121. }
  122. old_state := r.state
  123. r.state = old_state * 6364136223846793005 + (r.inc|1)
  124. xor_shifted := (((old_state >> 59) + 5) ~ old_state) * 12605985483714917081
  125. rot := (old_state >> 59)
  126. return (xor_shifted >> rot) | (xor_shifted << ((-rot) & 63))
  127. }
  128. /*
  129. Generates a random 32 bit value using the provided random number generator. If no generator is provided the global random number generator will be used.
  130. Inputs:
  131. - r: The random number generator to use, or nil for the global generator
  132. Returns:
  133. - val: A random unsigned 32 bit value
  134. Example:
  135. import "core:math/rand"
  136. import "core:fmt"
  137. uint32_example :: proc() {
  138. // Using the global random number generator
  139. fmt.println(rand.uint32())
  140. // Using local random number generator
  141. my_rand := rand.create(1)
  142. fmt.println(rand.uint32(&my_rand))
  143. }
  144. Possible Output:
  145. 10
  146. 389
  147. */
  148. @(require_results)
  149. uint32 :: proc(r: ^Rand = nil) -> (val: u32) { return u32(_random_u64(r)) }
  150. /*
  151. Generates a random 64 bit value using the provided random number generator. If no generator is provided the global random number generator will be used.
  152. Inputs:
  153. - r: The random number generator to use, or nil for the global generator
  154. Returns:
  155. - val: A random unsigned 64 bit value
  156. Example:
  157. import "core:math/rand"
  158. import "core:fmt"
  159. uint64_example :: proc() {
  160. // Using the global random number generator
  161. fmt.println(rand.uint64())
  162. // Using local random number generator
  163. my_rand := rand.create(1)
  164. fmt.println(rand.uint64(&my_rand))
  165. }
  166. Possible Output:
  167. 10
  168. 389
  169. */
  170. @(require_results)
  171. uint64 :: proc(r: ^Rand = nil) -> (val: u64) { return _random_u64(r) }
  172. /*
  173. Generates a random 128 bit value using the provided random number generator. If no generator is provided the global random number generator will be used.
  174. Inputs:
  175. - r: The random number generator to use, or nil for the global generator
  176. Returns:
  177. - val: A random unsigned 128 bit value
  178. Example:
  179. import "core:math/rand"
  180. import "core:fmt"
  181. uint128_example :: proc() {
  182. // Using the global random number generator
  183. fmt.println(rand.uint128())
  184. // Using local random number generator
  185. my_rand := rand.create(1)
  186. fmt.println(rand.uint128(&my_rand))
  187. }
  188. Possible Output:
  189. 10
  190. 389
  191. */
  192. @(require_results)
  193. uint128 :: proc(r: ^Rand = nil) -> (val: u128) {
  194. a := u128(_random_u64(r))
  195. b := u128(_random_u64(r))
  196. return (a<<64) | b
  197. }
  198. /*
  199. Generates a random 31 bit value using the provided random number generator. If no generator is provided the global random number generator will be used.
  200. The sign bit will always be set to 0, thus all generated numbers will be positive.
  201. Inputs:
  202. - r: The random number generator to use, or nil for the global generator
  203. Returns:
  204. - val: A random 31 bit value
  205. Example:
  206. import "core:math/rand"
  207. import "core:fmt"
  208. int31_example :: proc() {
  209. // Using the global random number generator
  210. fmt.println(rand.int31())
  211. // Using local random number generator
  212. my_rand := rand.create(1)
  213. fmt.println(rand.int31(&my_rand))
  214. }
  215. Possible Output:
  216. 10
  217. 389
  218. */
  219. @(require_results) int31 :: proc(r: ^Rand = nil) -> (val: i32) { return i32(uint32(r) << 1 >> 1) }
  220. /*
  221. Generates a random 63 bit value using the provided random number generator. If no generator is provided the global random number generator will be used.
  222. The sign bit will always be set to 0, thus all generated numbers will be positive.
  223. Inputs:
  224. - r: The random number generator to use, or nil for the global generator
  225. Returns:
  226. - val: A random 63 bit value
  227. Example:
  228. import "core:math/rand"
  229. import "core:fmt"
  230. int63_example :: proc() {
  231. // Using the global random number generator
  232. fmt.println(rand.int63())
  233. // Using local random number generator
  234. my_rand := rand.create(1)
  235. fmt.println(rand.int63(&my_rand))
  236. }
  237. Possible Output:
  238. 10
  239. 389
  240. */
  241. @(require_results) int63 :: proc(r: ^Rand = nil) -> (val: i64) { return i64(uint64(r) << 1 >> 1) }
  242. /*
  243. Generates a random 127 bit value using the provided random number generator. If no generator is provided the global random number generator will be used.
  244. The sign bit will always be set to 0, thus all generated numbers will be positive.
  245. Inputs:
  246. - r: The random number generator to use, or nil for the global generator
  247. Returns:
  248. - val: A random 127 bit value
  249. Example:
  250. import "core:math/rand"
  251. import "core:fmt"
  252. int127_example :: proc() {
  253. // Using the global random number generator
  254. fmt.println(rand.int127())
  255. // Using local random number generator
  256. my_rand := rand.create(1)
  257. fmt.println(rand.int127(&my_rand))
  258. }
  259. Possible Output:
  260. 10
  261. 389
  262. */
  263. @(require_results) int127 :: proc(r: ^Rand = nil) -> (val: i128) { return i128(uint128(r) << 1 >> 1) }
  264. /*
  265. Generates a random 31 bit value in the range `[0, n)` using the provided random number generator. If no generator is provided the global random number generator will be used.
  266. Inputs:
  267. - n: The upper bound of the generated number, this value is exclusive
  268. - r: The random number generator to use, or nil for the global generator
  269. Returns:
  270. - val: A random 31 bit value in the range `[0, n)`
  271. WARNING: Panics if n is less than 0
  272. Example:
  273. import "core:math/rand"
  274. import "core:fmt"
  275. int31_max_example :: proc() {
  276. // Using the global random number generator
  277. fmt.println(rand.int31_max(16))
  278. // Using local random number generator
  279. my_rand := rand.create(1)
  280. fmt.println(rand.int31_max(1024, &my_rand))
  281. }
  282. Possible Output:
  283. 6
  284. 500
  285. */
  286. @(require_results)
  287. int31_max :: proc(n: i32, r: ^Rand = nil) -> (val: i32) {
  288. if n <= 0 {
  289. panic("Invalid argument to int31_max")
  290. }
  291. if n&(n-1) == 0 {
  292. return int31(r) & (n-1)
  293. }
  294. max := i32((1<<31) - 1 - (1<<31)%u32(n))
  295. v := int31(r)
  296. for v > max {
  297. v = int31(r)
  298. }
  299. return v % n
  300. }
  301. /*
  302. Generates a random 63 bit value in the range `[0, n)` using the provided random number generator. If no generator is provided the global random number generator will be used.
  303. Inputs:
  304. - n: The upper bound of the generated number, this value is exclusive
  305. - r: The random number generator to use, or nil for the global generator
  306. Returns:
  307. - val: A random 63 bit value in the range `[0, n)`
  308. WARNING: Panics if n is less than 0
  309. Example:
  310. import "core:math/rand"
  311. import "core:fmt"
  312. int63_max_example :: proc() {
  313. // Using the global random number generator
  314. fmt.println(rand.int63_max(16))
  315. // Using local random number generator
  316. my_rand := rand.create(1)
  317. fmt.println(rand.int63_max(1024, &my_rand))
  318. }
  319. Possible Output:
  320. 6
  321. 500
  322. */
  323. @(require_results)
  324. int63_max :: proc(n: i64, r: ^Rand = nil) -> (val: i64) {
  325. if n <= 0 {
  326. panic("Invalid argument to int63_max")
  327. }
  328. if n&(n-1) == 0 {
  329. return int63(r) & (n-1)
  330. }
  331. max := i64((1<<63) - 1 - (1<<63)%u64(n))
  332. v := int63(r)
  333. for v > max {
  334. v = int63(r)
  335. }
  336. return v % n
  337. }
  338. /*
  339. Generates a random 127 bit value in the range `[0, n)` using the provided random number generator. If no generator is provided the global random number generator will be used.
  340. Inputs:
  341. - n: The upper bound of the generated number, this value is exclusive
  342. - r: The random number generator to use, or nil for the global generator
  343. Returns:
  344. - val: A random 127 bit value in the range `[0, n)`
  345. WARNING: Panics if n is less than 0
  346. Example:
  347. import "core:math/rand"
  348. import "core:fmt"
  349. int127_max_example :: proc() {
  350. // Using the global random number generator
  351. fmt.println(rand.int127_max(16))
  352. // Using local random number generator
  353. my_rand := rand.create(1)
  354. fmt.println(rand.int127_max(1024, &my_rand))
  355. }
  356. Possible Output:
  357. 6
  358. 500
  359. */
  360. @(require_results)
  361. int127_max :: proc(n: i128, r: ^Rand = nil) -> (val: i128) {
  362. if n <= 0 {
  363. panic("Invalid argument to int127_max")
  364. }
  365. if n&(n-1) == 0 {
  366. return int127(r) & (n-1)
  367. }
  368. max := i128((1<<127) - 1 - (1<<127)%u128(n))
  369. v := int127(r)
  370. for v > max {
  371. v = int127(r)
  372. }
  373. return v % n
  374. }
  375. /*
  376. Generates a random integer value in the range `[0, n)` using the provided random number generator. If no generator is provided the global random number generator will be used.
  377. Inputs:
  378. - n: The upper bound of the generated number, this value is exclusive
  379. - r: The random number generator to use, or nil for the global generator
  380. Returns:
  381. - val: A random integer value in the range `[0, n)`
  382. WARNING: Panics if n is less than 0
  383. Example:
  384. import "core:math/rand"
  385. import "core:fmt"
  386. int_max_example :: proc() {
  387. // Using the global random number generator
  388. fmt.println(rand.int_max(16))
  389. // Using local random number generator
  390. my_rand := rand.create(1)
  391. fmt.println(rand.int_max(1024, &my_rand))
  392. }
  393. Possible Output:
  394. 6
  395. 500
  396. */
  397. @(require_results)
  398. int_max :: proc(n: int, r: ^Rand = nil) -> (val: int) {
  399. if n <= 0 {
  400. panic("Invalid argument to int_max")
  401. }
  402. when size_of(int) == 4 {
  403. return int(int31_max(i32(n), r))
  404. } else {
  405. return int(int63_max(i64(n), r))
  406. }
  407. }
  408. /*
  409. Generates a random double floating point value in the range `[0, 1)` using the provided random number generator. If no generator is provided the global random number generator will be used.
  410. Inputs:
  411. - r: The random number generator to use, or nil for the global generator
  412. Returns:
  413. - val: A random double floating point value in the range `[0, 1)`
  414. Example:
  415. import "core:math/rand"
  416. import "core:fmt"
  417. float64_example :: proc() {
  418. // Using the global random number generator
  419. fmt.println(rand.float64())
  420. // Using local random number generator
  421. my_rand := rand.create(1)
  422. fmt.println(rand.float64(&my_rand))
  423. }
  424. Possible Output:
  425. 0.043
  426. 0.511
  427. */
  428. @(require_results) float64 :: proc(r: ^Rand = nil) -> (val: f64) { return f64(int63_max(1<<53, r)) / (1 << 53) }
  429. /*
  430. Generates a random single floating point value in the range `[0, 1)` using the provided random number generator. If no generator is provided the global random number generator will be used.
  431. Inputs:
  432. - r: The random number generator to use, or nil for the global generator
  433. Returns:
  434. - val: A random single floating point value in the range `[0, 1)`
  435. Example:
  436. import "core:math/rand"
  437. import "core:fmt"
  438. float32_example :: proc() {
  439. // Using the global random number generator
  440. fmt.println(rand.float32())
  441. // Using local random number generator
  442. my_rand := rand.create(1)
  443. fmt.println(rand.float32(&my_rand))
  444. }
  445. Possible Output:
  446. 0.043
  447. 0.511
  448. */
  449. @(require_results) float32 :: proc(r: ^Rand = nil) -> (val: f32) { return f32(int31_max(1<<24, r)) / (1 << 24) }
  450. /*
  451. Generates a random double floating point value in the range `[low, high)` using the provided random number generator. If no generator is provided the global random number generator will be used.
  452. WARNING: Panics if `high < low`
  453. Inputs:
  454. - low: The lower bounds of the value, this value is inclusive
  455. - high: The upper bounds of the value, this value is exclusive
  456. - r: The random number generator to use, or nil for the global generator
  457. Returns:
  458. - val: A random double floating point value in the range [low, high)
  459. Example:
  460. import "core:math/rand"
  461. import "core:fmt"
  462. float64_range_example :: proc() {
  463. // Using the global random number generator
  464. fmt.println(rand.float64_range(-10, 300))
  465. // Using local random number generator
  466. my_rand := rand.create(1)
  467. fmt.println(rand.float64_range(600, 900, &my_rand))
  468. }
  469. Possible Output:
  470. 15.312
  471. 673.130
  472. */
  473. @(require_results) float64_range :: proc(low, high: f64, r: ^Rand = nil) -> (val: f64) {
  474. assert(low <= high, "low must be lower than or equal to high")
  475. val = (high-low)*float64(r) + low
  476. if val >= high {
  477. val = max(low, high * (1 - math.F64_EPSILON))
  478. }
  479. return
  480. }
  481. /*
  482. Generates a random single floating point value in the range `[low, high)` using the provided random number generator. If no generator is provided the global random number generator will be used.
  483. Inputs:
  484. - low: The lower bounds of the value, this value is inclusive
  485. - high: The upper bounds of the value, this value is exclusive
  486. - r: The random number generator to use, or nil for the global generator
  487. Returns:
  488. - val: A random single floating point value in the range [low, high)
  489. WARNING: Panics if `high < low`
  490. Example:
  491. import "core:math/rand"
  492. import "core:fmt"
  493. float32_range_example :: proc() {
  494. // Using the global random number generator
  495. fmt.println(rand.float32_range(-10, 300))
  496. // Using local random number generator
  497. my_rand := rand.create(1)
  498. fmt.println(rand.float32_range(600, 900, &my_rand))
  499. }
  500. Possible Output:
  501. 15.312
  502. 673.130
  503. */
  504. @(require_results) float32_range :: proc(low, high: f32, r: ^Rand = nil) -> (val: f32) {
  505. assert(low <= high, "low must be lower than or equal to high")
  506. val = (high-low)*float32(r) + low
  507. if val >= high {
  508. val = max(low, high * (1 - math.F32_EPSILON))
  509. }
  510. return
  511. }
  512. /*
  513. Fills a byte slice with random values using the provided random number generator. If no generator is provided the global random number generator will be used.
  514. Due to floating point precision there is no guarantee if the upper and lower bounds are inclusive/exclusive with the exact floating point value.
  515. Inputs:
  516. - p: The byte slice to fill
  517. - r: The random number generator to use, or nil for the global generator
  518. Returns:
  519. - n: The number of bytes generated
  520. Example:
  521. import "core:math/rand"
  522. import "core:fmt"
  523. read_example :: proc() {
  524. // Using the global random number generator
  525. data: [8]byte
  526. n := rand.read(data[:])
  527. fmt.println(n)
  528. fmt.println(data)
  529. }
  530. Possible Output:
  531. 8
  532. [32, 4, 59, 7, 1, 2, 2, 119]
  533. */
  534. @(require_results)
  535. read :: proc(p: []byte, r: ^Rand = nil) -> (n: int) {
  536. pos := i8(0)
  537. val := i64(0)
  538. for n = 0; n < len(p); n += 1 {
  539. if pos == 0 {
  540. val = int63(r)
  541. pos = 7
  542. }
  543. p[n] = byte(val)
  544. val >>= 8
  545. pos -= 1
  546. }
  547. return
  548. }
  549. /*
  550. Creates a slice of `int` filled with random values using the provided random number generator. If no generator is provided the global random number generator will be used.
  551. *Allocates Using Provided Allocator*
  552. Inputs:
  553. - n: The size of the created slice
  554. - r: The random number generator to use, or nil for the global generator
  555. - allocator: (default: context.allocator)
  556. Returns:
  557. - res: A slice filled with random values
  558. - err: An allocator error if one occured, `nil` otherwise
  559. Example:
  560. import "core:math/rand"
  561. import "core:mem"
  562. import "core:fmt"
  563. perm_example :: proc() -> (err: mem.Allocator_Error) {
  564. // Using the global random number generator and using the context allocator
  565. data := rand.perm(4) or_return
  566. fmt.println(data)
  567. defer delete(data, context.allocator)
  568. // Using local random number generator and temp allocator
  569. my_rand := rand.create(1)
  570. data_tmp := rand.perm(4, &my_rand, context.temp_allocator) or_return
  571. fmt.println(data_tmp)
  572. return
  573. }
  574. Possible Output:
  575. [7201011, 3, 9123, 231131]
  576. [19578, 910081, 131, 7]
  577. */
  578. @(require_results)
  579. perm :: proc(n: int, r: ^Rand = nil, allocator := context.allocator) -> (res: []int, err: mem.Allocator_Error) #optional_allocator_error {
  580. m := make([]int, n, allocator) or_return
  581. for i := 0; i < n; i += 1 {
  582. j := int_max(i+1, r)
  583. m[i] = m[j]
  584. m[j] = i
  585. }
  586. return m, {}
  587. }
  588. /*
  589. Randomizes the ordering of elements for the provided slice. If no generator is provided the global random number generator will be used.
  590. Inputs:
  591. - array: The slice to randomize
  592. - r: The random number generator to use, or nil for the global generator
  593. Example:
  594. import "core:math/rand"
  595. import "core:fmt"
  596. shuffle_example :: proc() {
  597. // Using the global random number generator
  598. data: [4]int = { 1, 2, 3, 4 }
  599. fmt.println(data) // the contents are in order
  600. rand.shuffle(data[:])
  601. fmt.println(data) // the contents have been shuffled
  602. }
  603. Possible Output:
  604. [1, 2, 3, 4]
  605. [2, 4, 3, 1]
  606. */
  607. shuffle :: proc(array: $T/[]$E, r: ^Rand = nil) {
  608. n := i64(len(array))
  609. if n < 2 {
  610. return
  611. }
  612. for i := i64(n - 1); i > 0; i -= 1 {
  613. j := int63_max(i + 1, r)
  614. array[i], array[j] = array[j], array[i]
  615. }
  616. }
  617. /*
  618. Returns a random element from the provided slice. If no generator is provided the global random number generator will be used.
  619. Inputs:
  620. - array: The slice to choose an element from
  621. - r: The random number generator to use, or nil for the global generator
  622. Returns:
  623. - res: A random element from `array`
  624. Example:
  625. import "core:math/rand"
  626. import "core:fmt"
  627. choice_example :: proc() {
  628. // Using the global random number generator
  629. data: [4]int = { 1, 2, 3, 4 }
  630. fmt.println(rand.choice(data[:]))
  631. fmt.println(rand.choice(data[:]))
  632. fmt.println(rand.choice(data[:]))
  633. fmt.println(rand.choice(data[:]))
  634. }
  635. Possible Output:
  636. 3
  637. 2
  638. 2
  639. 4
  640. */
  641. @(require_results)
  642. choice :: proc(array: $T/[]$E, r: ^Rand = nil) -> (res: E) {
  643. n := i64(len(array))
  644. if n < 1 {
  645. return E{}
  646. }
  647. return array[int63_max(n, r)]
  648. }
  649. @(require_results)
  650. choice_enum :: proc($T: typeid, r: ^Rand = nil) -> T
  651. where
  652. intrinsics.type_is_enum(T),
  653. size_of(T) <= 8,
  654. len(T) == cap(T) /* Only allow contiguous enum types */
  655. {
  656. when intrinsics.type_is_unsigned(intrinsics.type_core_type(T)) &&
  657. u64(max(T)) > u64(max(i64)) {
  658. i := uint64(r) % u64(len(T))
  659. i += u64(min(T))
  660. return T(i)
  661. } else {
  662. i := int63_max(i64(len(T)), r)
  663. i += i64(min(T))
  664. return T(i)
  665. }
  666. }