Path: blob/main/sys/contrib/pcg-c/include/pcg_variants.h
48260 views
/*1* PCG Random Number Generation for C.2*3* Copyright 2014-2019 Melissa O'Neill <[email protected]>,4* and the PCG Project contributors.5*6* SPDX-License-Identifier: (Apache-2.0 OR MIT)7*8* Licensed under the Apache License, Version 2.0 (provided in9* LICENSE-APACHE.txt and at http://www.apache.org/licenses/LICENSE-2.0)10* or under the MIT license (provided in LICENSE-MIT.txt and at11* http://opensource.org/licenses/MIT), at your option. This file may not12* be copied, modified, or distributed except according to those terms.13*14* Distributed on an "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, either15* express or implied. See your chosen license for details.16*17* For additional information about the PCG random number generation scheme,18* visit http://www.pcg-random.org/.19*/2021/*22* This code is derived from the canonical C++ PCG implementation, which23* has many additional features and is preferable if you can use C++ in24* your project.25*26* Much of the derivation was performed mechanically. In particular, the27* output functions were generated by compiling the C++ output functions28* into LLVM bitcode and then transforming that using the LLVM C backend29* (from https://github.com/draperlaboratory/llvm-cbe), and then30* postprocessing and hand editing the output.31*32* Much of the remaining code was generated by C-preprocessor metaprogramming.33*/3435#ifndef PCG_VARIANTS_H_INCLUDED36#define PCG_VARIANTS_H_INCLUDED 13738#if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__39typedef __uint128_t pcg128_t;40#define PCG_128BIT_CONSTANT(high,low) \41((((pcg128_t)high) << 64) + low)42#define PCG_HAS_128BIT_OPS 143#else44#define PCG_HAS_128BIT_OPS 045#endif4647#ifdef __cplusplus48extern "C" {49#endif5051/*52* Rotate helper functions.53*/5455static inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot)56{57/* Unfortunately, clang is kinda pathetic when it comes to properly58* recognizing idiomatic rotate code, so for clang we actually provide59* assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss.60*/61#if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__))62__asm__ ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));63return value;64#else65return (value >> rot) | (value << ((- rot) & 7));66#endif67}6869static inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot)70{71#if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__))72__asm__ ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));73return value;74#else75return (value >> rot) | (value << ((- rot) & 15));76#endif77}7879static inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot)80{81#if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__))82__asm__ ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));83return value;84#else85return (value >> rot) | (value << ((- rot) & 31));86#endif87}8889static inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot)90{91#if 0 && PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__))92/* For whatever reason, clang actually *does* generate rotq by93itself, so we don't need this code. */94__asm__ ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));95return value;96#else97return (value >> rot) | (value << ((- rot) & 63));98#endif99}100101#if PCG_HAS_128BIT_OPS102static inline pcg128_t pcg_rotr_128(pcg128_t value, unsigned int rot)103{104return (value >> rot) | (value << ((- rot) & 127));105}106#endif107108/*109* Output functions. These are the core of the PCG generation scheme.110*/111112/* XSH RS */113114static inline uint8_t pcg_output_xsh_rs_16_8(uint16_t state)115{116return (uint8_t)(((state >> 7u) ^ state) >> ((state >> 14u) + 3u));117}118119static inline uint16_t pcg_output_xsh_rs_32_16(uint32_t state)120{121return (uint16_t)(((state >> 11u) ^ state) >> ((state >> 30u) + 11u));122}123124static inline uint32_t pcg_output_xsh_rs_64_32(uint64_t state)125{126127return (uint32_t)(((state >> 22u) ^ state) >> ((state >> 61u) + 22u));128}129130#if PCG_HAS_128BIT_OPS131static inline uint64_t pcg_output_xsh_rs_128_64(pcg128_t state)132{133return (uint64_t)(((state >> 43u) ^ state) >> ((state >> 124u) + 45u));134}135#endif136137/* XSH RR */138139static inline uint8_t pcg_output_xsh_rr_16_8(uint16_t state)140{141return pcg_rotr_8(((state >> 5u) ^ state) >> 5u, state >> 13u);142}143144static inline uint16_t pcg_output_xsh_rr_32_16(uint32_t state)145{146return pcg_rotr_16(((state >> 10u) ^ state) >> 12u, state >> 28u);147}148149static inline uint32_t pcg_output_xsh_rr_64_32(uint64_t state)150{151return pcg_rotr_32(((state >> 18u) ^ state) >> 27u, state >> 59u);152}153154#if PCG_HAS_128BIT_OPS155static inline uint64_t pcg_output_xsh_rr_128_64(pcg128_t state)156{157return pcg_rotr_64(((state >> 35u) ^ state) >> 58u, state >> 122u);158}159#endif160161/* RXS M XS */162163static inline uint8_t pcg_output_rxs_m_xs_8_8(uint8_t state)164{165uint8_t word = ((state >> ((state >> 6u) + 2u)) ^ state) * 217u;166return (word >> 6u) ^ word;167}168169static inline uint16_t pcg_output_rxs_m_xs_16_16(uint16_t state)170{171uint16_t word = ((state >> ((state >> 13u) + 3u)) ^ state) * 62169u;172return (word >> 11u) ^ word;173}174175static inline uint32_t pcg_output_rxs_m_xs_32_32(uint32_t state)176{177uint32_t word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;178return (word >> 22u) ^ word;179}180181static inline uint64_t pcg_output_rxs_m_xs_64_64(uint64_t state)182{183uint64_t word = ((state >> ((state >> 59u) + 5u)) ^ state)184* 12605985483714917081ull;185return (word >> 43u) ^ word;186}187188#if PCG_HAS_128BIT_OPS189static inline pcg128_t pcg_output_rxs_m_xs_128_128(pcg128_t state)190{191pcg128_t word = ((state >> ((state >> 122u) + 6u)) ^ state)192* (PCG_128BIT_CONSTANT(17766728186571221404ULL,19312605985483714917081ULL));194/* 327738287884841127335028083622016905945 */195return (word >> 86u) ^ word;196}197#endif198199/* RXS M */200201static inline uint8_t pcg_output_rxs_m_16_8(uint16_t state)202{203return (((state >> ((state >> 13u) + 3u)) ^ state) * 62169u) >> 8u;204}205206static inline uint16_t pcg_output_rxs_m_32_16(uint32_t state)207{208return (((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u) >> 16u;209}210211static inline uint32_t pcg_output_rxs_m_64_32(uint64_t state)212{213return (((state >> ((state >> 59u) + 5u)) ^ state)214* 12605985483714917081ull) >> 32u;215}216217#if PCG_HAS_128BIT_OPS218static inline uint64_t pcg_output_rxs_m_128_64(pcg128_t state)219{220return (((state >> ((state >> 122u) + 6u)) ^ state)221* (PCG_128BIT_CONSTANT(17766728186571221404ULL,22212605985483714917081ULL))) >> 64u;223/* 327738287884841127335028083622016905945 */224}225#endif226227/* XSL RR (only defined for >= 64 bits) */228229static inline uint32_t pcg_output_xsl_rr_64_32(uint64_t state)230{231return pcg_rotr_32(((uint32_t)(state >> 32u)) ^ (uint32_t)state,232state >> 59u);233}234235#if PCG_HAS_128BIT_OPS236static inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state)237{238return pcg_rotr_64(((uint64_t)(state >> 64u)) ^ (uint64_t)state,239state >> 122u);240}241#endif242243/* XSL RR RR (only defined for >= 64 bits) */244245static inline uint64_t pcg_output_xsl_rr_rr_64_64(uint64_t state)246{247uint32_t rot1 = (uint32_t)(state >> 59u);248uint32_t high = (uint32_t)(state >> 32u);249uint32_t low = (uint32_t)state;250uint32_t xored = high ^ low;251uint32_t newlow = pcg_rotr_32(xored, rot1);252uint32_t newhigh = pcg_rotr_32(high, newlow & 31u);253return (((uint64_t)newhigh) << 32u) | newlow;254}255256#if PCG_HAS_128BIT_OPS257static inline pcg128_t pcg_output_xsl_rr_rr_128_128(pcg128_t state)258{259uint32_t rot1 = (uint32_t)(state >> 122u);260uint64_t high = (uint64_t)(state >> 64u);261uint64_t low = (uint64_t)state;262uint64_t xored = high ^ low;263uint64_t newlow = pcg_rotr_64(xored, rot1);264uint64_t newhigh = pcg_rotr_64(high, newlow & 63u);265return (((pcg128_t)newhigh) << 64u) | newlow;266}267#endif268269#define PCG_DEFAULT_MULTIPLIER_8 141U270#define PCG_DEFAULT_MULTIPLIER_16 12829U271#define PCG_DEFAULT_MULTIPLIER_32 747796405U272#define PCG_DEFAULT_MULTIPLIER_64 6364136223846793005ULL273274#define PCG_DEFAULT_INCREMENT_8 77U275#define PCG_DEFAULT_INCREMENT_16 47989U276#define PCG_DEFAULT_INCREMENT_32 2891336453U277#define PCG_DEFAULT_INCREMENT_64 1442695040888963407ULL278279#if PCG_HAS_128BIT_OPS280#define PCG_DEFAULT_MULTIPLIER_128 \281PCG_128BIT_CONSTANT(2549297995355413924ULL,4865540595714422341ULL)282#define PCG_DEFAULT_INCREMENT_128 \283PCG_128BIT_CONSTANT(6364136223846793005ULL,1442695040888963407ULL)284#endif285286/*287* Static initialization constants (if you can't call srandom for some288* bizarre reason).289*/290291#define PCG_STATE_ONESEQ_8_INITIALIZER { 0xd7U }292#define PCG_STATE_ONESEQ_16_INITIALIZER { 0x20dfU }293#define PCG_STATE_ONESEQ_32_INITIALIZER { 0x46b56677U }294#define PCG_STATE_ONESEQ_64_INITIALIZER { 0x4d595df4d0f33173ULL }295#if PCG_HAS_128BIT_OPS296#define PCG_STATE_ONESEQ_128_INITIALIZER \297{ PCG_128BIT_CONSTANT(0xb8dc10e158a92392ULL, 0x98046df007ec0a53ULL) }298#endif299300#define PCG_STATE_UNIQUE_8_INITIALIZER PCG_STATE_ONESEQ_8_INITIALIZER301#define PCG_STATE_UNIQUE_16_INITIALIZER PCG_STATE_ONESEQ_16_INITIALIZER302#define PCG_STATE_UNIQUE_32_INITIALIZER PCG_STATE_ONESEQ_32_INITIALIZER303#define PCG_STATE_UNIQUE_64_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER304#if PCG_HAS_128BIT_OPS305#define PCG_STATE_UNIQUE_128_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER306#endif307308#define PCG_STATE_MCG_8_INITIALIZER { 0xe5U }309#define PCG_STATE_MCG_16_INITIALIZER { 0xa5e5U }310#define PCG_STATE_MCG_32_INITIALIZER { 0xd15ea5e5U }311#define PCG_STATE_MCG_64_INITIALIZER { 0xcafef00dd15ea5e5ULL }312#if PCG_HAS_128BIT_OPS313#define PCG_STATE_MCG_128_INITIALIZER \314{ PCG_128BIT_CONSTANT(0x0000000000000000ULL, 0xcafef00dd15ea5e5ULL) }315#endif316317#define PCG_STATE_SETSEQ_8_INITIALIZER { 0x9bU, 0xdbU }318#define PCG_STATE_SETSEQ_16_INITIALIZER { 0xe39bU, 0x5bdbU }319#define PCG_STATE_SETSEQ_32_INITIALIZER { 0xec02d89bU, 0x94b95bdbU }320#define PCG_STATE_SETSEQ_64_INITIALIZER \321{ 0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL }322#if PCG_HAS_128BIT_OPS323#define PCG_STATE_SETSEQ_128_INITIALIZER \324{ PCG_128BIT_CONSTANT(0x979c9a98d8462005ULL, 0x7d3e9cb6cfe0549bULL), \325PCG_128BIT_CONSTANT(0x0000000000000001ULL, 0xda3e39cb94b95bdbULL) }326#endif327328/* Representations for the oneseq, mcg, and unique variants */329330struct pcg_state_8 {331uint8_t state;332};333334struct pcg_state_16 {335uint16_t state;336};337338struct pcg_state_32 {339uint32_t state;340};341342struct pcg_state_64 {343uint64_t state;344};345346#if PCG_HAS_128BIT_OPS347struct pcg_state_128 {348pcg128_t state;349};350#endif351352/* Representations setseq variants */353354struct pcg_state_setseq_8 {355uint8_t state;356uint8_t inc;357};358359struct pcg_state_setseq_16 {360uint16_t state;361uint16_t inc;362};363364struct pcg_state_setseq_32 {365uint32_t state;366uint32_t inc;367};368369struct pcg_state_setseq_64 {370uint64_t state;371uint64_t inc;372};373374#if PCG_HAS_128BIT_OPS375struct pcg_state_setseq_128 {376pcg128_t state;377pcg128_t inc;378};379#endif380381/* Multi-step advance functions (jump-ahead, jump-back) */382383extern uint8_t pcg_advance_lcg_8(uint8_t state, uint8_t delta, uint8_t cur_mult,384uint8_t cur_plus);385extern uint16_t pcg_advance_lcg_16(uint16_t state, uint16_t delta,386uint16_t cur_mult, uint16_t cur_plus);387extern uint32_t pcg_advance_lcg_32(uint32_t state, uint32_t delta,388uint32_t cur_mult, uint32_t cur_plus);389extern uint64_t pcg_advance_lcg_64(uint64_t state, uint64_t delta,390uint64_t cur_mult, uint64_t cur_plus);391392#if PCG_HAS_128BIT_OPS393extern pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta,394pcg128_t cur_mult, pcg128_t cur_plus);395#endif396397/* Functions to advance the underlying LCG, one version for each size and398* each style. These functions are considered semi-private. There is rarely399* a good reason to call them directly.400*/401402static inline void pcg_oneseq_8_step_r(struct pcg_state_8* rng)403{404rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8405+ PCG_DEFAULT_INCREMENT_8;406}407408static inline void pcg_oneseq_8_advance_r(struct pcg_state_8* rng, uint8_t delta)409{410rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8,411PCG_DEFAULT_INCREMENT_8);412}413414static inline void pcg_mcg_8_step_r(struct pcg_state_8* rng)415{416rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8;417}418419static inline void pcg_mcg_8_advance_r(struct pcg_state_8* rng, uint8_t delta)420{421rng->state422= pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, 0u);423}424425static inline void pcg_unique_8_step_r(struct pcg_state_8* rng)426{427rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8428+ (uint8_t)(((intptr_t)rng) | 1u);429}430431static inline void pcg_unique_8_advance_r(struct pcg_state_8* rng, uint8_t delta)432{433rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8,434(uint8_t)(((intptr_t)rng) | 1u));435}436437static inline void pcg_setseq_8_step_r(struct pcg_state_setseq_8* rng)438{439rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8 + rng->inc;440}441442static inline void pcg_setseq_8_advance_r(struct pcg_state_setseq_8* rng,443uint8_t delta)444{445rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8,446rng->inc);447}448449static inline void pcg_oneseq_16_step_r(struct pcg_state_16* rng)450{451rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16452+ PCG_DEFAULT_INCREMENT_16;453}454455static inline void pcg_oneseq_16_advance_r(struct pcg_state_16* rng, uint16_t delta)456{457rng->state = pcg_advance_lcg_16(458rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, PCG_DEFAULT_INCREMENT_16);459}460461static inline void pcg_mcg_16_step_r(struct pcg_state_16* rng)462{463rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16;464}465466static inline void pcg_mcg_16_advance_r(struct pcg_state_16* rng, uint16_t delta)467{468rng->state469= pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, 0u);470}471472static inline void pcg_unique_16_step_r(struct pcg_state_16* rng)473{474rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16475+ (uint16_t)(((intptr_t)rng) | 1u);476}477478static inline void pcg_unique_16_advance_r(struct pcg_state_16* rng, uint16_t delta)479{480rng->state481= pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16,482(uint16_t)(((intptr_t)rng) | 1u));483}484485static inline void pcg_setseq_16_step_r(struct pcg_state_setseq_16* rng)486{487rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16 + rng->inc;488}489490static inline void pcg_setseq_16_advance_r(struct pcg_state_setseq_16* rng,491uint16_t delta)492{493rng->state = pcg_advance_lcg_16(rng->state, delta,494PCG_DEFAULT_MULTIPLIER_16, rng->inc);495}496497static inline void pcg_oneseq_32_step_r(struct pcg_state_32* rng)498{499rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32500+ PCG_DEFAULT_INCREMENT_32;501}502503static inline void pcg_oneseq_32_advance_r(struct pcg_state_32* rng, uint32_t delta)504{505rng->state = pcg_advance_lcg_32(506rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, PCG_DEFAULT_INCREMENT_32);507}508509static inline void pcg_mcg_32_step_r(struct pcg_state_32* rng)510{511rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32;512}513514static inline void pcg_mcg_32_advance_r(struct pcg_state_32* rng, uint32_t delta)515{516rng->state517= pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, 0u);518}519520static inline void pcg_unique_32_step_r(struct pcg_state_32* rng)521{522rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32523+ (uint32_t)(((intptr_t)rng) | 1u);524}525526static inline void pcg_unique_32_advance_r(struct pcg_state_32* rng, uint32_t delta)527{528rng->state529= pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32,530(uint32_t)(((intptr_t)rng) | 1u));531}532533static inline void pcg_setseq_32_step_r(struct pcg_state_setseq_32* rng)534{535rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32 + rng->inc;536}537538static inline void pcg_setseq_32_advance_r(struct pcg_state_setseq_32* rng,539uint32_t delta)540{541rng->state = pcg_advance_lcg_32(rng->state, delta,542PCG_DEFAULT_MULTIPLIER_32, rng->inc);543}544545static inline void pcg_oneseq_64_step_r(struct pcg_state_64* rng)546{547rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64548+ PCG_DEFAULT_INCREMENT_64;549}550551static inline void pcg_oneseq_64_advance_r(struct pcg_state_64* rng, uint64_t delta)552{553rng->state = pcg_advance_lcg_64(554rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, PCG_DEFAULT_INCREMENT_64);555}556557static inline void pcg_mcg_64_step_r(struct pcg_state_64* rng)558{559rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64;560}561562static inline void pcg_mcg_64_advance_r(struct pcg_state_64* rng, uint64_t delta)563{564rng->state565= pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, 0u);566}567568static inline void pcg_unique_64_step_r(struct pcg_state_64* rng)569{570rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64571+ (uint64_t)(((intptr_t)rng) | 1u);572}573574static inline void pcg_unique_64_advance_r(struct pcg_state_64* rng, uint64_t delta)575{576rng->state577= pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64,578(uint64_t)(((intptr_t)rng) | 1u));579}580581static inline void pcg_setseq_64_step_r(struct pcg_state_setseq_64* rng)582{583rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 + rng->inc;584}585586static inline void pcg_setseq_64_advance_r(struct pcg_state_setseq_64* rng,587uint64_t delta)588{589rng->state = pcg_advance_lcg_64(rng->state, delta,590PCG_DEFAULT_MULTIPLIER_64, rng->inc);591}592593#if PCG_HAS_128BIT_OPS594static inline void pcg_oneseq_128_step_r(struct pcg_state_128* rng)595{596rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128597+ PCG_DEFAULT_INCREMENT_128;598}599#endif600601#if PCG_HAS_128BIT_OPS602static inline void pcg_oneseq_128_advance_r(struct pcg_state_128* rng, pcg128_t delta)603{604rng->state605= pcg_advance_lcg_128(rng->state, delta, PCG_DEFAULT_MULTIPLIER_128,606PCG_DEFAULT_INCREMENT_128);607}608#endif609610#if PCG_HAS_128BIT_OPS611static inline void pcg_mcg_128_step_r(struct pcg_state_128* rng)612{613rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128;614}615#endif616617#if PCG_HAS_128BIT_OPS618static inline void pcg_mcg_128_advance_r(struct pcg_state_128* rng, pcg128_t delta)619{620rng->state = pcg_advance_lcg_128(rng->state, delta,621PCG_DEFAULT_MULTIPLIER_128, 0u);622}623#endif624625#if PCG_HAS_128BIT_OPS626static inline void pcg_unique_128_step_r(struct pcg_state_128* rng)627{628rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128629+ (pcg128_t)(((intptr_t)rng) | 1u);630}631#endif632633#if PCG_HAS_128BIT_OPS634static inline void pcg_unique_128_advance_r(struct pcg_state_128* rng, pcg128_t delta)635{636rng->state637= pcg_advance_lcg_128(rng->state, delta, PCG_DEFAULT_MULTIPLIER_128,638(pcg128_t)(((intptr_t)rng) | 1u));639}640#endif641642#if PCG_HAS_128BIT_OPS643static inline void pcg_setseq_128_step_r(struct pcg_state_setseq_128* rng)644{645rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128 + rng->inc;646}647#endif648649#if PCG_HAS_128BIT_OPS650static inline void pcg_setseq_128_advance_r(struct pcg_state_setseq_128* rng,651pcg128_t delta)652{653rng->state = pcg_advance_lcg_128(rng->state, delta,654PCG_DEFAULT_MULTIPLIER_128, rng->inc);655}656#endif657658/* Functions to seed the RNG state, one version for each size and each659* style. Unlike the step functions, regular users can and should call660* these functions.661*/662663static inline void pcg_oneseq_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate)664{665rng->state = 0U;666pcg_oneseq_8_step_r(rng);667rng->state += initstate;668pcg_oneseq_8_step_r(rng);669}670671static inline void pcg_mcg_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate)672{673rng->state = initstate | 1u;674}675676static inline void pcg_unique_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate)677{678rng->state = 0U;679pcg_unique_8_step_r(rng);680rng->state += initstate;681pcg_unique_8_step_r(rng);682}683684static inline void pcg_setseq_8_srandom_r(struct pcg_state_setseq_8* rng,685uint8_t initstate, uint8_t initseq)686{687rng->state = 0U;688rng->inc = (initseq << 1u) | 1u;689pcg_setseq_8_step_r(rng);690rng->state += initstate;691pcg_setseq_8_step_r(rng);692}693694static inline void pcg_oneseq_16_srandom_r(struct pcg_state_16* rng,695uint16_t initstate)696{697rng->state = 0U;698pcg_oneseq_16_step_r(rng);699rng->state += initstate;700pcg_oneseq_16_step_r(rng);701}702703static inline void pcg_mcg_16_srandom_r(struct pcg_state_16* rng, uint16_t initstate)704{705rng->state = initstate | 1u;706}707708static inline void pcg_unique_16_srandom_r(struct pcg_state_16* rng,709uint16_t initstate)710{711rng->state = 0U;712pcg_unique_16_step_r(rng);713rng->state += initstate;714pcg_unique_16_step_r(rng);715}716717static inline void pcg_setseq_16_srandom_r(struct pcg_state_setseq_16* rng,718uint16_t initstate, uint16_t initseq)719{720rng->state = 0U;721rng->inc = (initseq << 1u) | 1u;722pcg_setseq_16_step_r(rng);723rng->state += initstate;724pcg_setseq_16_step_r(rng);725}726727static inline void pcg_oneseq_32_srandom_r(struct pcg_state_32* rng,728uint32_t initstate)729{730rng->state = 0U;731pcg_oneseq_32_step_r(rng);732rng->state += initstate;733pcg_oneseq_32_step_r(rng);734}735736static inline void pcg_mcg_32_srandom_r(struct pcg_state_32* rng, uint32_t initstate)737{738rng->state = initstate | 1u;739}740741static inline void pcg_unique_32_srandom_r(struct pcg_state_32* rng,742uint32_t initstate)743{744rng->state = 0U;745pcg_unique_32_step_r(rng);746rng->state += initstate;747pcg_unique_32_step_r(rng);748}749750static inline void pcg_setseq_32_srandom_r(struct pcg_state_setseq_32* rng,751uint32_t initstate, uint32_t initseq)752{753rng->state = 0U;754rng->inc = (initseq << 1u) | 1u;755pcg_setseq_32_step_r(rng);756rng->state += initstate;757pcg_setseq_32_step_r(rng);758}759760static inline void pcg_oneseq_64_srandom_r(struct pcg_state_64* rng,761uint64_t initstate)762{763rng->state = 0U;764pcg_oneseq_64_step_r(rng);765rng->state += initstate;766pcg_oneseq_64_step_r(rng);767}768769static inline void pcg_mcg_64_srandom_r(struct pcg_state_64* rng, uint64_t initstate)770{771rng->state = initstate | 1u;772}773774static inline void pcg_unique_64_srandom_r(struct pcg_state_64* rng,775uint64_t initstate)776{777rng->state = 0U;778pcg_unique_64_step_r(rng);779rng->state += initstate;780pcg_unique_64_step_r(rng);781}782783static inline void pcg_setseq_64_srandom_r(struct pcg_state_setseq_64* rng,784uint64_t initstate, uint64_t initseq)785{786rng->state = 0U;787rng->inc = (initseq << 1u) | 1u;788pcg_setseq_64_step_r(rng);789rng->state += initstate;790pcg_setseq_64_step_r(rng);791}792793#if PCG_HAS_128BIT_OPS794static inline void pcg_oneseq_128_srandom_r(struct pcg_state_128* rng,795pcg128_t initstate)796{797rng->state = 0U;798pcg_oneseq_128_step_r(rng);799rng->state += initstate;800pcg_oneseq_128_step_r(rng);801}802#endif803804#if PCG_HAS_128BIT_OPS805static inline void pcg_mcg_128_srandom_r(struct pcg_state_128* rng, pcg128_t initstate)806{807rng->state = initstate | 1u;808}809#endif810811#if PCG_HAS_128BIT_OPS812static inline void pcg_unique_128_srandom_r(struct pcg_state_128* rng,813pcg128_t initstate)814{815rng->state = 0U;816pcg_unique_128_step_r(rng);817rng->state += initstate;818pcg_unique_128_step_r(rng);819}820#endif821822#if PCG_HAS_128BIT_OPS823static inline void pcg_setseq_128_srandom_r(struct pcg_state_setseq_128* rng,824pcg128_t initstate, pcg128_t initseq)825{826rng->state = 0U;827rng->inc = (initseq << 1u) | 1u;828pcg_setseq_128_step_r(rng);829rng->state += initstate;830pcg_setseq_128_step_r(rng);831}832#endif833834/* Now, finally we create each of the individual generators. We provide835* a random_r function that provides a random number of the appropriate836* type (using the full range of the type) and a boundedrand_r version837* that provides838*839* Implementation notes for boundedrand_r:840*841* To avoid bias, we need to make the range of the RNG a multiple of842* bound, which we do by dropping output less than a threshold.843* Let's consider a 32-bit case... A naive scheme to calculate the844* threshold would be to do845*846* uint32_t threshold = 0x100000000ull % bound;847*848* but 64-bit div/mod is slower than 32-bit div/mod (especially on849* 32-bit platforms). In essence, we do850*851* uint32_t threshold = (0x100000000ull-bound) % bound;852*853* because this version will calculate the same modulus, but the LHS854* value is less than 2^32.855*856* (Note that using modulo is only wise for good RNGs, poorer RNGs857* such as raw LCGs do better using a technique based on division.)858* Empricical tests show that division is preferable to modulus for859* reducting the range of an RNG. It's faster, and sometimes it can860* even be statistically prefereable.861*/862863/* Generation functions for XSH RS */864865static inline uint8_t pcg_oneseq_16_xsh_rs_8_random_r(struct pcg_state_16* rng)866{867uint16_t oldstate = rng->state;868pcg_oneseq_16_step_r(rng);869return pcg_output_xsh_rs_16_8(oldstate);870}871872static inline uint8_t pcg_oneseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng,873uint8_t bound)874{875uint8_t threshold = ((uint8_t)(-bound)) % bound;876for (;;) {877uint8_t r = pcg_oneseq_16_xsh_rs_8_random_r(rng);878if (r >= threshold)879return r % bound;880}881}882883static inline uint16_t pcg_oneseq_32_xsh_rs_16_random_r(struct pcg_state_32* rng)884{885uint32_t oldstate = rng->state;886pcg_oneseq_32_step_r(rng);887return pcg_output_xsh_rs_32_16(oldstate);888}889890static inline uint16_t pcg_oneseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng,891uint16_t bound)892{893uint16_t threshold = ((uint16_t)(-bound)) % bound;894for (;;) {895uint16_t r = pcg_oneseq_32_xsh_rs_16_random_r(rng);896if (r >= threshold)897return r % bound;898}899}900901static inline uint32_t pcg_oneseq_64_xsh_rs_32_random_r(struct pcg_state_64* rng)902{903uint64_t oldstate = rng->state;904pcg_oneseq_64_step_r(rng);905return pcg_output_xsh_rs_64_32(oldstate);906}907908static inline uint32_t pcg_oneseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng,909uint32_t bound)910{911uint32_t threshold = -bound % bound;912for (;;) {913uint32_t r = pcg_oneseq_64_xsh_rs_32_random_r(rng);914if (r >= threshold)915return r % bound;916}917}918919#if PCG_HAS_128BIT_OPS920static inline uint64_t pcg_oneseq_128_xsh_rs_64_random_r(struct pcg_state_128* rng)921{922pcg_oneseq_128_step_r(rng);923return pcg_output_xsh_rs_128_64(rng->state);924}925#endif926927#if PCG_HAS_128BIT_OPS928static inline uint64_t929pcg_oneseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,930uint64_t bound)931{932uint64_t threshold = -bound % bound;933for (;;) {934uint64_t r = pcg_oneseq_128_xsh_rs_64_random_r(rng);935if (r >= threshold)936return r % bound;937}938}939#endif940941static inline uint8_t pcg_unique_16_xsh_rs_8_random_r(struct pcg_state_16* rng)942{943uint16_t oldstate = rng->state;944pcg_unique_16_step_r(rng);945return pcg_output_xsh_rs_16_8(oldstate);946}947948static inline uint8_t pcg_unique_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng,949uint8_t bound)950{951uint8_t threshold = ((uint8_t)(-bound)) % bound;952for (;;) {953uint8_t r = pcg_unique_16_xsh_rs_8_random_r(rng);954if (r >= threshold)955return r % bound;956}957}958959static inline uint16_t pcg_unique_32_xsh_rs_16_random_r(struct pcg_state_32* rng)960{961uint32_t oldstate = rng->state;962pcg_unique_32_step_r(rng);963return pcg_output_xsh_rs_32_16(oldstate);964}965966static inline uint16_t pcg_unique_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng,967uint16_t bound)968{969uint16_t threshold = ((uint16_t)(-bound)) % bound;970for (;;) {971uint16_t r = pcg_unique_32_xsh_rs_16_random_r(rng);972if (r >= threshold)973return r % bound;974}975}976977static inline uint32_t pcg_unique_64_xsh_rs_32_random_r(struct pcg_state_64* rng)978{979uint64_t oldstate = rng->state;980pcg_unique_64_step_r(rng);981return pcg_output_xsh_rs_64_32(oldstate);982}983984static inline uint32_t pcg_unique_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng,985uint32_t bound)986{987uint32_t threshold = -bound % bound;988for (;;) {989uint32_t r = pcg_unique_64_xsh_rs_32_random_r(rng);990if (r >= threshold)991return r % bound;992}993}994995#if PCG_HAS_128BIT_OPS996static inline uint64_t pcg_unique_128_xsh_rs_64_random_r(struct pcg_state_128* rng)997{998pcg_unique_128_step_r(rng);999return pcg_output_xsh_rs_128_64(rng->state);1000}1001#endif10021003#if PCG_HAS_128BIT_OPS1004static inline uint64_t1005pcg_unique_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,1006uint64_t bound)1007{1008uint64_t threshold = -bound % bound;1009for (;;) {1010uint64_t r = pcg_unique_128_xsh_rs_64_random_r(rng);1011if (r >= threshold)1012return r % bound;1013}1014}1015#endif10161017static inline uint8_t pcg_setseq_16_xsh_rs_8_random_r(struct pcg_state_setseq_16* rng)1018{1019uint16_t oldstate = rng->state;1020pcg_setseq_16_step_r(rng);1021return pcg_output_xsh_rs_16_8(oldstate);1022}10231024static inline uint8_t1025pcg_setseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_setseq_16* rng,1026uint8_t bound)1027{1028uint8_t threshold = ((uint8_t)(-bound)) % bound;1029for (;;) {1030uint8_t r = pcg_setseq_16_xsh_rs_8_random_r(rng);1031if (r >= threshold)1032return r % bound;1033}1034}10351036static inline uint16_t1037pcg_setseq_32_xsh_rs_16_random_r(struct pcg_state_setseq_32* rng)1038{1039uint32_t oldstate = rng->state;1040pcg_setseq_32_step_r(rng);1041return pcg_output_xsh_rs_32_16(oldstate);1042}10431044static inline uint16_t1045pcg_setseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_setseq_32* rng,1046uint16_t bound)1047{1048uint16_t threshold = ((uint16_t)(-bound)) % bound;1049for (;;) {1050uint16_t r = pcg_setseq_32_xsh_rs_16_random_r(rng);1051if (r >= threshold)1052return r % bound;1053}1054}10551056static inline uint32_t1057pcg_setseq_64_xsh_rs_32_random_r(struct pcg_state_setseq_64* rng)1058{1059uint64_t oldstate = rng->state;1060pcg_setseq_64_step_r(rng);1061return pcg_output_xsh_rs_64_32(oldstate);1062}10631064static inline uint32_t1065pcg_setseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_setseq_64* rng,1066uint32_t bound)1067{1068uint32_t threshold = -bound % bound;1069for (;;) {1070uint32_t r = pcg_setseq_64_xsh_rs_32_random_r(rng);1071if (r >= threshold)1072return r % bound;1073}1074}10751076#if PCG_HAS_128BIT_OPS1077static inline uint64_t1078pcg_setseq_128_xsh_rs_64_random_r(struct pcg_state_setseq_128* rng)1079{1080pcg_setseq_128_step_r(rng);1081return pcg_output_xsh_rs_128_64(rng->state);1082}1083#endif10841085#if PCG_HAS_128BIT_OPS1086static inline uint64_t1087pcg_setseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_setseq_128* rng,1088uint64_t bound)1089{1090uint64_t threshold = -bound % bound;1091for (;;) {1092uint64_t r = pcg_setseq_128_xsh_rs_64_random_r(rng);1093if (r >= threshold)1094return r % bound;1095}1096}1097#endif10981099static inline uint8_t pcg_mcg_16_xsh_rs_8_random_r(struct pcg_state_16* rng)1100{1101uint16_t oldstate = rng->state;1102pcg_mcg_16_step_r(rng);1103return pcg_output_xsh_rs_16_8(oldstate);1104}11051106static inline uint8_t pcg_mcg_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng,1107uint8_t bound)1108{1109uint8_t threshold = ((uint8_t)(-bound)) % bound;1110for (;;) {1111uint8_t r = pcg_mcg_16_xsh_rs_8_random_r(rng);1112if (r >= threshold)1113return r % bound;1114}1115}11161117static inline uint16_t pcg_mcg_32_xsh_rs_16_random_r(struct pcg_state_32* rng)1118{1119uint32_t oldstate = rng->state;1120pcg_mcg_32_step_r(rng);1121return pcg_output_xsh_rs_32_16(oldstate);1122}11231124static inline uint16_t pcg_mcg_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng,1125uint16_t bound)1126{1127uint16_t threshold = ((uint16_t)(-bound)) % bound;1128for (;;) {1129uint16_t r = pcg_mcg_32_xsh_rs_16_random_r(rng);1130if (r >= threshold)1131return r % bound;1132}1133}11341135static inline uint32_t pcg_mcg_64_xsh_rs_32_random_r(struct pcg_state_64* rng)1136{1137uint64_t oldstate = rng->state;1138pcg_mcg_64_step_r(rng);1139return pcg_output_xsh_rs_64_32(oldstate);1140}11411142static inline uint32_t pcg_mcg_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng,1143uint32_t bound)1144{1145uint32_t threshold = -bound % bound;1146for (;;) {1147uint32_t r = pcg_mcg_64_xsh_rs_32_random_r(rng);1148if (r >= threshold)1149return r % bound;1150}1151}11521153#if PCG_HAS_128BIT_OPS1154static inline uint64_t pcg_mcg_128_xsh_rs_64_random_r(struct pcg_state_128* rng)1155{1156pcg_mcg_128_step_r(rng);1157return pcg_output_xsh_rs_128_64(rng->state);1158}1159#endif11601161#if PCG_HAS_128BIT_OPS1162static inline uint64_t pcg_mcg_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,1163uint64_t bound)1164{1165uint64_t threshold = -bound % bound;1166for (;;) {1167uint64_t r = pcg_mcg_128_xsh_rs_64_random_r(rng);1168if (r >= threshold)1169return r % bound;1170}1171}1172#endif11731174/* Generation functions for XSH RR */11751176static inline uint8_t pcg_oneseq_16_xsh_rr_8_random_r(struct pcg_state_16* rng)1177{1178uint16_t oldstate = rng->state;1179pcg_oneseq_16_step_r(rng);1180return pcg_output_xsh_rr_16_8(oldstate);1181}11821183static inline uint8_t pcg_oneseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng,1184uint8_t bound)1185{1186uint8_t threshold = ((uint8_t)(-bound)) % bound;1187for (;;) {1188uint8_t r = pcg_oneseq_16_xsh_rr_8_random_r(rng);1189if (r >= threshold)1190return r % bound;1191}1192}11931194static inline uint16_t pcg_oneseq_32_xsh_rr_16_random_r(struct pcg_state_32* rng)1195{1196uint32_t oldstate = rng->state;1197pcg_oneseq_32_step_r(rng);1198return pcg_output_xsh_rr_32_16(oldstate);1199}12001201static inline uint16_t pcg_oneseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng,1202uint16_t bound)1203{1204uint16_t threshold = ((uint16_t)(-bound)) % bound;1205for (;;) {1206uint16_t r = pcg_oneseq_32_xsh_rr_16_random_r(rng);1207if (r >= threshold)1208return r % bound;1209}1210}12111212static inline uint32_t pcg_oneseq_64_xsh_rr_32_random_r(struct pcg_state_64* rng)1213{1214uint64_t oldstate = rng->state;1215pcg_oneseq_64_step_r(rng);1216return pcg_output_xsh_rr_64_32(oldstate);1217}12181219static inline uint32_t pcg_oneseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng,1220uint32_t bound)1221{1222uint32_t threshold = -bound % bound;1223for (;;) {1224uint32_t r = pcg_oneseq_64_xsh_rr_32_random_r(rng);1225if (r >= threshold)1226return r % bound;1227}1228}12291230#if PCG_HAS_128BIT_OPS1231static inline uint64_t pcg_oneseq_128_xsh_rr_64_random_r(struct pcg_state_128* rng)1232{1233pcg_oneseq_128_step_r(rng);1234return pcg_output_xsh_rr_128_64(rng->state);1235}1236#endif12371238#if PCG_HAS_128BIT_OPS1239static inline uint64_t1240pcg_oneseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,1241uint64_t bound)1242{1243uint64_t threshold = -bound % bound;1244for (;;) {1245uint64_t r = pcg_oneseq_128_xsh_rr_64_random_r(rng);1246if (r >= threshold)1247return r % bound;1248}1249}1250#endif12511252static inline uint8_t pcg_unique_16_xsh_rr_8_random_r(struct pcg_state_16* rng)1253{1254uint16_t oldstate = rng->state;1255pcg_unique_16_step_r(rng);1256return pcg_output_xsh_rr_16_8(oldstate);1257}12581259static inline uint8_t pcg_unique_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng,1260uint8_t bound)1261{1262uint8_t threshold = ((uint8_t)(-bound)) % bound;1263for (;;) {1264uint8_t r = pcg_unique_16_xsh_rr_8_random_r(rng);1265if (r >= threshold)1266return r % bound;1267}1268}12691270static inline uint16_t pcg_unique_32_xsh_rr_16_random_r(struct pcg_state_32* rng)1271{1272uint32_t oldstate = rng->state;1273pcg_unique_32_step_r(rng);1274return pcg_output_xsh_rr_32_16(oldstate);1275}12761277static inline uint16_t pcg_unique_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng,1278uint16_t bound)1279{1280uint16_t threshold = ((uint16_t)(-bound)) % bound;1281for (;;) {1282uint16_t r = pcg_unique_32_xsh_rr_16_random_r(rng);1283if (r >= threshold)1284return r % bound;1285}1286}12871288static inline uint32_t pcg_unique_64_xsh_rr_32_random_r(struct pcg_state_64* rng)1289{1290uint64_t oldstate = rng->state;1291pcg_unique_64_step_r(rng);1292return pcg_output_xsh_rr_64_32(oldstate);1293}12941295static inline uint32_t pcg_unique_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng,1296uint32_t bound)1297{1298uint32_t threshold = -bound % bound;1299for (;;) {1300uint32_t r = pcg_unique_64_xsh_rr_32_random_r(rng);1301if (r >= threshold)1302return r % bound;1303}1304}13051306#if PCG_HAS_128BIT_OPS1307static inline uint64_t pcg_unique_128_xsh_rr_64_random_r(struct pcg_state_128* rng)1308{1309pcg_unique_128_step_r(rng);1310return pcg_output_xsh_rr_128_64(rng->state);1311}1312#endif13131314#if PCG_HAS_128BIT_OPS1315static inline uint64_t1316pcg_unique_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,1317uint64_t bound)1318{1319uint64_t threshold = -bound % bound;1320for (;;) {1321uint64_t r = pcg_unique_128_xsh_rr_64_random_r(rng);1322if (r >= threshold)1323return r % bound;1324}1325}1326#endif13271328static inline uint8_t pcg_setseq_16_xsh_rr_8_random_r(struct pcg_state_setseq_16* rng)1329{1330uint16_t oldstate = rng->state;1331pcg_setseq_16_step_r(rng);1332return pcg_output_xsh_rr_16_8(oldstate);1333}13341335static inline uint8_t1336pcg_setseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_setseq_16* rng,1337uint8_t bound)1338{1339uint8_t threshold = ((uint8_t)(-bound)) % bound;1340for (;;) {1341uint8_t r = pcg_setseq_16_xsh_rr_8_random_r(rng);1342if (r >= threshold)1343return r % bound;1344}1345}13461347static inline uint16_t1348pcg_setseq_32_xsh_rr_16_random_r(struct pcg_state_setseq_32* rng)1349{1350uint32_t oldstate = rng->state;1351pcg_setseq_32_step_r(rng);1352return pcg_output_xsh_rr_32_16(oldstate);1353}13541355static inline uint16_t1356pcg_setseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_setseq_32* rng,1357uint16_t bound)1358{1359uint16_t threshold = ((uint16_t)(-bound)) % bound;1360for (;;) {1361uint16_t r = pcg_setseq_32_xsh_rr_16_random_r(rng);1362if (r >= threshold)1363return r % bound;1364}1365}13661367static inline uint32_t1368pcg_setseq_64_xsh_rr_32_random_r(struct pcg_state_setseq_64* rng)1369{1370uint64_t oldstate = rng->state;1371pcg_setseq_64_step_r(rng);1372return pcg_output_xsh_rr_64_32(oldstate);1373}13741375static inline uint32_t1376pcg_setseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng,1377uint32_t bound)1378{1379uint32_t threshold = -bound % bound;1380for (;;) {1381uint32_t r = pcg_setseq_64_xsh_rr_32_random_r(rng);1382if (r >= threshold)1383return r % bound;1384}1385}13861387#if PCG_HAS_128BIT_OPS1388static inline uint64_t1389pcg_setseq_128_xsh_rr_64_random_r(struct pcg_state_setseq_128* rng)1390{1391pcg_setseq_128_step_r(rng);1392return pcg_output_xsh_rr_128_64(rng->state);1393}1394#endif13951396#if PCG_HAS_128BIT_OPS1397static inline uint64_t1398pcg_setseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng,1399uint64_t bound)1400{1401uint64_t threshold = -bound % bound;1402for (;;) {1403uint64_t r = pcg_setseq_128_xsh_rr_64_random_r(rng);1404if (r >= threshold)1405return r % bound;1406}1407}1408#endif14091410static inline uint8_t pcg_mcg_16_xsh_rr_8_random_r(struct pcg_state_16* rng)1411{1412uint16_t oldstate = rng->state;1413pcg_mcg_16_step_r(rng);1414return pcg_output_xsh_rr_16_8(oldstate);1415}14161417static inline uint8_t pcg_mcg_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng,1418uint8_t bound)1419{1420uint8_t threshold = ((uint8_t)(-bound)) % bound;1421for (;;) {1422uint8_t r = pcg_mcg_16_xsh_rr_8_random_r(rng);1423if (r >= threshold)1424return r % bound;1425}1426}14271428static inline uint16_t pcg_mcg_32_xsh_rr_16_random_r(struct pcg_state_32* rng)1429{1430uint32_t oldstate = rng->state;1431pcg_mcg_32_step_r(rng);1432return pcg_output_xsh_rr_32_16(oldstate);1433}14341435static inline uint16_t pcg_mcg_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng,1436uint16_t bound)1437{1438uint16_t threshold = ((uint16_t)(-bound)) % bound;1439for (;;) {1440uint16_t r = pcg_mcg_32_xsh_rr_16_random_r(rng);1441if (r >= threshold)1442return r % bound;1443}1444}14451446static inline uint32_t pcg_mcg_64_xsh_rr_32_random_r(struct pcg_state_64* rng)1447{1448uint64_t oldstate = rng->state;1449pcg_mcg_64_step_r(rng);1450return pcg_output_xsh_rr_64_32(oldstate);1451}14521453static inline uint32_t pcg_mcg_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng,1454uint32_t bound)1455{1456uint32_t threshold = -bound % bound;1457for (;;) {1458uint32_t r = pcg_mcg_64_xsh_rr_32_random_r(rng);1459if (r >= threshold)1460return r % bound;1461}1462}14631464#if PCG_HAS_128BIT_OPS1465static inline uint64_t pcg_mcg_128_xsh_rr_64_random_r(struct pcg_state_128* rng)1466{1467pcg_mcg_128_step_r(rng);1468return pcg_output_xsh_rr_128_64(rng->state);1469}1470#endif14711472#if PCG_HAS_128BIT_OPS1473static inline uint64_t pcg_mcg_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,1474uint64_t bound)1475{1476uint64_t threshold = -bound % bound;1477for (;;) {1478uint64_t r = pcg_mcg_128_xsh_rr_64_random_r(rng);1479if (r >= threshold)1480return r % bound;1481}1482}1483#endif14841485/* Generation functions for RXS M XS (no MCG versions because they1486* don't make sense when you want to use the entire state)1487*/14881489static inline uint8_t pcg_oneseq_8_rxs_m_xs_8_random_r(struct pcg_state_8* rng)1490{1491uint8_t oldstate = rng->state;1492pcg_oneseq_8_step_r(rng);1493return pcg_output_rxs_m_xs_8_8(oldstate);1494}14951496static inline uint8_t pcg_oneseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_8* rng,1497uint8_t bound)1498{1499uint8_t threshold = ((uint8_t)(-bound)) % bound;1500for (;;) {1501uint8_t r = pcg_oneseq_8_rxs_m_xs_8_random_r(rng);1502if (r >= threshold)1503return r % bound;1504}1505}15061507static inline uint16_t pcg_oneseq_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng)1508{1509uint16_t oldstate = rng->state;1510pcg_oneseq_16_step_r(rng);1511return pcg_output_rxs_m_xs_16_16(oldstate);1512}15131514static inline uint16_t1515pcg_oneseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng,1516uint16_t bound)1517{1518uint16_t threshold = ((uint16_t)(-bound)) % bound;1519for (;;) {1520uint16_t r = pcg_oneseq_16_rxs_m_xs_16_random_r(rng);1521if (r >= threshold)1522return r % bound;1523}1524}15251526static inline uint32_t pcg_oneseq_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng)1527{1528uint32_t oldstate = rng->state;1529pcg_oneseq_32_step_r(rng);1530return pcg_output_rxs_m_xs_32_32(oldstate);1531}15321533static inline uint32_t1534pcg_oneseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng,1535uint32_t bound)1536{1537uint32_t threshold = -bound % bound;1538for (;;) {1539uint32_t r = pcg_oneseq_32_rxs_m_xs_32_random_r(rng);1540if (r >= threshold)1541return r % bound;1542}1543}15441545static inline uint64_t pcg_oneseq_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng)1546{1547uint64_t oldstate = rng->state;1548pcg_oneseq_64_step_r(rng);1549return pcg_output_rxs_m_xs_64_64(oldstate);1550}15511552static inline uint64_t1553pcg_oneseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng,1554uint64_t bound)1555{1556uint64_t threshold = -bound % bound;1557for (;;) {1558uint64_t r = pcg_oneseq_64_rxs_m_xs_64_random_r(rng);1559if (r >= threshold)1560return r % bound;1561}1562}15631564#if PCG_HAS_128BIT_OPS1565static inline pcg128_t pcg_oneseq_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng)1566{1567pcg_oneseq_128_step_r(rng);1568return pcg_output_rxs_m_xs_128_128(rng->state);1569}1570#endif15711572#if PCG_HAS_128BIT_OPS1573static inline pcg128_t1574pcg_oneseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng,1575pcg128_t bound)1576{1577pcg128_t threshold = -bound % bound;1578for (;;) {1579pcg128_t r = pcg_oneseq_128_rxs_m_xs_128_random_r(rng);1580if (r >= threshold)1581return r % bound;1582}1583}1584#endif15851586static inline uint16_t pcg_unique_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng)1587{1588uint16_t oldstate = rng->state;1589pcg_unique_16_step_r(rng);1590return pcg_output_rxs_m_xs_16_16(oldstate);1591}15921593static inline uint16_t1594pcg_unique_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng,1595uint16_t bound)1596{1597uint16_t threshold = ((uint16_t)(-bound)) % bound;1598for (;;) {1599uint16_t r = pcg_unique_16_rxs_m_xs_16_random_r(rng);1600if (r >= threshold)1601return r % bound;1602}1603}16041605static inline uint32_t pcg_unique_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng)1606{1607uint32_t oldstate = rng->state;1608pcg_unique_32_step_r(rng);1609return pcg_output_rxs_m_xs_32_32(oldstate);1610}16111612static inline uint32_t1613pcg_unique_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng,1614uint32_t bound)1615{1616uint32_t threshold = -bound % bound;1617for (;;) {1618uint32_t r = pcg_unique_32_rxs_m_xs_32_random_r(rng);1619if (r >= threshold)1620return r % bound;1621}1622}16231624static inline uint64_t pcg_unique_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng)1625{1626uint64_t oldstate = rng->state;1627pcg_unique_64_step_r(rng);1628return pcg_output_rxs_m_xs_64_64(oldstate);1629}16301631static inline uint64_t1632pcg_unique_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng,1633uint64_t bound)1634{1635uint64_t threshold = -bound % bound;1636for (;;) {1637uint64_t r = pcg_unique_64_rxs_m_xs_64_random_r(rng);1638if (r >= threshold)1639return r % bound;1640}1641}16421643#if PCG_HAS_128BIT_OPS1644static inline pcg128_t pcg_unique_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng)1645{1646pcg_unique_128_step_r(rng);1647return pcg_output_rxs_m_xs_128_128(rng->state);1648}1649#endif16501651#if PCG_HAS_128BIT_OPS1652static inline pcg128_t1653pcg_unique_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng,1654pcg128_t bound)1655{1656pcg128_t threshold = -bound % bound;1657for (;;) {1658pcg128_t r = pcg_unique_128_rxs_m_xs_128_random_r(rng);1659if (r >= threshold)1660return r % bound;1661}1662}1663#endif16641665static inline uint8_t pcg_setseq_8_rxs_m_xs_8_random_r(struct pcg_state_setseq_8* rng)1666{1667uint8_t oldstate = rng->state;1668pcg_setseq_8_step_r(rng);1669return pcg_output_rxs_m_xs_8_8(oldstate);1670}16711672static inline uint8_t1673pcg_setseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_setseq_8* rng,1674uint8_t bound)1675{1676uint8_t threshold = ((uint8_t)(-bound)) % bound;1677for (;;) {1678uint8_t r = pcg_setseq_8_rxs_m_xs_8_random_r(rng);1679if (r >= threshold)1680return r % bound;1681}1682}16831684static inline uint16_t1685pcg_setseq_16_rxs_m_xs_16_random_r(struct pcg_state_setseq_16* rng)1686{1687uint16_t oldstate = rng->state;1688pcg_setseq_16_step_r(rng);1689return pcg_output_rxs_m_xs_16_16(oldstate);1690}16911692static inline uint16_t1693pcg_setseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_setseq_16* rng,1694uint16_t bound)1695{1696uint16_t threshold = ((uint16_t)(-bound)) % bound;1697for (;;) {1698uint16_t r = pcg_setseq_16_rxs_m_xs_16_random_r(rng);1699if (r >= threshold)1700return r % bound;1701}1702}17031704static inline uint32_t1705pcg_setseq_32_rxs_m_xs_32_random_r(struct pcg_state_setseq_32* rng)1706{1707uint32_t oldstate = rng->state;1708pcg_setseq_32_step_r(rng);1709return pcg_output_rxs_m_xs_32_32(oldstate);1710}17111712static inline uint32_t1713pcg_setseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_setseq_32* rng,1714uint32_t bound)1715{1716uint32_t threshold = -bound % bound;1717for (;;) {1718uint32_t r = pcg_setseq_32_rxs_m_xs_32_random_r(rng);1719if (r >= threshold)1720return r % bound;1721}1722}17231724static inline uint64_t1725pcg_setseq_64_rxs_m_xs_64_random_r(struct pcg_state_setseq_64* rng)1726{1727uint64_t oldstate = rng->state;1728pcg_setseq_64_step_r(rng);1729return pcg_output_rxs_m_xs_64_64(oldstate);1730}17311732static inline uint64_t1733pcg_setseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_setseq_64* rng,1734uint64_t bound)1735{1736uint64_t threshold = -bound % bound;1737for (;;) {1738uint64_t r = pcg_setseq_64_rxs_m_xs_64_random_r(rng);1739if (r >= threshold)1740return r % bound;1741}1742}17431744#if PCG_HAS_128BIT_OPS1745static inline pcg128_t1746pcg_setseq_128_rxs_m_xs_128_random_r(struct pcg_state_setseq_128* rng)1747{1748pcg_setseq_128_step_r(rng);1749return pcg_output_rxs_m_xs_128_128(rng->state);1750}1751#endif17521753#if PCG_HAS_128BIT_OPS1754static inline pcg128_t1755pcg_setseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_setseq_128* rng,1756pcg128_t bound)1757{1758pcg128_t threshold = -bound % bound;1759for (;;) {1760pcg128_t r = pcg_setseq_128_rxs_m_xs_128_random_r(rng);1761if (r >= threshold)1762return r % bound;1763}1764}1765#endif17661767/* Generation functions for RXS M */17681769static inline uint8_t pcg_oneseq_16_rxs_m_8_random_r(struct pcg_state_16* rng)1770{1771uint16_t oldstate = rng->state;1772pcg_oneseq_16_step_r(rng);1773return pcg_output_rxs_m_16_8(oldstate);1774}17751776static inline uint8_t pcg_oneseq_16_rxs_m_8_boundedrand_r(struct pcg_state_16* rng,1777uint8_t bound)1778{1779uint8_t threshold = ((uint8_t)(-bound)) % bound;1780for (;;) {1781uint8_t r = pcg_oneseq_16_rxs_m_8_random_r(rng);1782if (r >= threshold)1783return r % bound;1784}1785}17861787static inline uint16_t pcg_oneseq_32_rxs_m_16_random_r(struct pcg_state_32* rng)1788{1789uint32_t oldstate = rng->state;1790pcg_oneseq_32_step_r(rng);1791return pcg_output_rxs_m_32_16(oldstate);1792}17931794static inline uint16_t pcg_oneseq_32_rxs_m_16_boundedrand_r(struct pcg_state_32* rng,1795uint16_t bound)1796{1797uint16_t threshold = ((uint16_t)(-bound)) % bound;1798for (;;) {1799uint16_t r = pcg_oneseq_32_rxs_m_16_random_r(rng);1800if (r >= threshold)1801return r % bound;1802}1803}18041805static inline uint32_t pcg_oneseq_64_rxs_m_32_random_r(struct pcg_state_64* rng)1806{1807uint64_t oldstate = rng->state;1808pcg_oneseq_64_step_r(rng);1809return pcg_output_rxs_m_64_32(oldstate);1810}18111812static inline uint32_t pcg_oneseq_64_rxs_m_32_boundedrand_r(struct pcg_state_64* rng,1813uint32_t bound)1814{1815uint32_t threshold = -bound % bound;1816for (;;) {1817uint32_t r = pcg_oneseq_64_rxs_m_32_random_r(rng);1818if (r >= threshold)1819return r % bound;1820}1821}18221823#if PCG_HAS_128BIT_OPS1824static inline uint64_t pcg_oneseq_128_rxs_m_64_random_r(struct pcg_state_128* rng)1825{1826pcg_oneseq_128_step_r(rng);1827return pcg_output_rxs_m_128_64(rng->state);1828}1829#endif18301831#if PCG_HAS_128BIT_OPS1832static inline uint64_t pcg_oneseq_128_rxs_m_64_boundedrand_r(struct pcg_state_128* rng,1833uint64_t bound)1834{1835uint64_t threshold = -bound % bound;1836for (;;) {1837uint64_t r = pcg_oneseq_128_rxs_m_64_random_r(rng);1838if (r >= threshold)1839return r % bound;1840}1841}1842#endif18431844static inline uint8_t pcg_unique_16_rxs_m_8_random_r(struct pcg_state_16* rng)1845{1846uint16_t oldstate = rng->state;1847pcg_unique_16_step_r(rng);1848return pcg_output_rxs_m_16_8(oldstate);1849}18501851static inline uint8_t pcg_unique_16_rxs_m_8_boundedrand_r(struct pcg_state_16* rng,1852uint8_t bound)1853{1854uint8_t threshold = ((uint8_t)(-bound)) % bound;1855for (;;) {1856uint8_t r = pcg_unique_16_rxs_m_8_random_r(rng);1857if (r >= threshold)1858return r % bound;1859}1860}18611862static inline uint16_t pcg_unique_32_rxs_m_16_random_r(struct pcg_state_32* rng)1863{1864uint32_t oldstate = rng->state;1865pcg_unique_32_step_r(rng);1866return pcg_output_rxs_m_32_16(oldstate);1867}18681869static inline uint16_t pcg_unique_32_rxs_m_16_boundedrand_r(struct pcg_state_32* rng,1870uint16_t bound)1871{1872uint16_t threshold = ((uint16_t)(-bound)) % bound;1873for (;;) {1874uint16_t r = pcg_unique_32_rxs_m_16_random_r(rng);1875if (r >= threshold)1876return r % bound;1877}1878}18791880static inline uint32_t pcg_unique_64_rxs_m_32_random_r(struct pcg_state_64* rng)1881{1882uint64_t oldstate = rng->state;1883pcg_unique_64_step_r(rng);1884return pcg_output_rxs_m_64_32(oldstate);1885}18861887static inline uint32_t pcg_unique_64_rxs_m_32_boundedrand_r(struct pcg_state_64* rng,1888uint32_t bound)1889{1890uint32_t threshold = -bound % bound;1891for (;;) {1892uint32_t r = pcg_unique_64_rxs_m_32_random_r(rng);1893if (r >= threshold)1894return r % bound;1895}1896}18971898#if PCG_HAS_128BIT_OPS1899static inline uint64_t pcg_unique_128_rxs_m_64_random_r(struct pcg_state_128* rng)1900{1901pcg_unique_128_step_r(rng);1902return pcg_output_rxs_m_128_64(rng->state);1903}1904#endif19051906#if PCG_HAS_128BIT_OPS1907static inline uint64_t pcg_unique_128_rxs_m_64_boundedrand_r(struct pcg_state_128* rng,1908uint64_t bound)1909{1910uint64_t threshold = -bound % bound;1911for (;;) {1912uint64_t r = pcg_unique_128_rxs_m_64_random_r(rng);1913if (r >= threshold)1914return r % bound;1915}1916}1917#endif19181919static inline uint8_t pcg_setseq_16_rxs_m_8_random_r(struct pcg_state_setseq_16* rng)1920{1921uint16_t oldstate = rng->state;1922pcg_setseq_16_step_r(rng);1923return pcg_output_rxs_m_16_8(oldstate);1924}19251926static inline uint8_t1927pcg_setseq_16_rxs_m_8_boundedrand_r(struct pcg_state_setseq_16* rng,1928uint8_t bound)1929{1930uint8_t threshold = ((uint8_t)(-bound)) % bound;1931for (;;) {1932uint8_t r = pcg_setseq_16_rxs_m_8_random_r(rng);1933if (r >= threshold)1934return r % bound;1935}1936}19371938static inline uint16_t pcg_setseq_32_rxs_m_16_random_r(struct pcg_state_setseq_32* rng)1939{1940uint32_t oldstate = rng->state;1941pcg_setseq_32_step_r(rng);1942return pcg_output_rxs_m_32_16(oldstate);1943}19441945static inline uint16_t1946pcg_setseq_32_rxs_m_16_boundedrand_r(struct pcg_state_setseq_32* rng,1947uint16_t bound)1948{1949uint16_t threshold = ((uint16_t)(-bound)) % bound;1950for (;;) {1951uint16_t r = pcg_setseq_32_rxs_m_16_random_r(rng);1952if (r >= threshold)1953return r % bound;1954}1955}19561957static inline uint32_t pcg_setseq_64_rxs_m_32_random_r(struct pcg_state_setseq_64* rng)1958{1959uint64_t oldstate = rng->state;1960pcg_setseq_64_step_r(rng);1961return pcg_output_rxs_m_64_32(oldstate);1962}19631964static inline uint32_t1965pcg_setseq_64_rxs_m_32_boundedrand_r(struct pcg_state_setseq_64* rng,1966uint32_t bound)1967{1968uint32_t threshold = -bound % bound;1969for (;;) {1970uint32_t r = pcg_setseq_64_rxs_m_32_random_r(rng);1971if (r >= threshold)1972return r % bound;1973}1974}19751976#if PCG_HAS_128BIT_OPS1977static inline uint64_t1978pcg_setseq_128_rxs_m_64_random_r(struct pcg_state_setseq_128* rng)1979{1980pcg_setseq_128_step_r(rng);1981return pcg_output_rxs_m_128_64(rng->state);1982}1983#endif19841985#if PCG_HAS_128BIT_OPS1986static inline uint64_t1987pcg_setseq_128_rxs_m_64_boundedrand_r(struct pcg_state_setseq_128* rng,1988uint64_t bound)1989{1990uint64_t threshold = -bound % bound;1991for (;;) {1992uint64_t r = pcg_setseq_128_rxs_m_64_random_r(rng);1993if (r >= threshold)1994return r % bound;1995}1996}1997#endif19981999static inline uint8_t pcg_mcg_16_rxs_m_8_random_r(struct pcg_state_16* rng)2000{2001uint16_t oldstate = rng->state;2002pcg_mcg_16_step_r(rng);2003return pcg_output_rxs_m_16_8(oldstate);2004}20052006static inline uint8_t pcg_mcg_16_rxs_m_8_boundedrand_r(struct pcg_state_16* rng,2007uint8_t bound)2008{2009uint8_t threshold = ((uint8_t)(-bound)) % bound;2010for (;;) {2011uint8_t r = pcg_mcg_16_rxs_m_8_random_r(rng);2012if (r >= threshold)2013return r % bound;2014}2015}20162017static inline uint16_t pcg_mcg_32_rxs_m_16_random_r(struct pcg_state_32* rng)2018{2019uint32_t oldstate = rng->state;2020pcg_mcg_32_step_r(rng);2021return pcg_output_rxs_m_32_16(oldstate);2022}20232024static inline uint16_t pcg_mcg_32_rxs_m_16_boundedrand_r(struct pcg_state_32* rng,2025uint16_t bound)2026{2027uint16_t threshold = ((uint16_t)(-bound)) % bound;2028for (;;) {2029uint16_t r = pcg_mcg_32_rxs_m_16_random_r(rng);2030if (r >= threshold)2031return r % bound;2032}2033}20342035static inline uint32_t pcg_mcg_64_rxs_m_32_random_r(struct pcg_state_64* rng)2036{2037uint64_t oldstate = rng->state;2038pcg_mcg_64_step_r(rng);2039return pcg_output_rxs_m_64_32(oldstate);2040}20412042static inline uint32_t pcg_mcg_64_rxs_m_32_boundedrand_r(struct pcg_state_64* rng,2043uint32_t bound)2044{2045uint32_t threshold = -bound % bound;2046for (;;) {2047uint32_t r = pcg_mcg_64_rxs_m_32_random_r(rng);2048if (r >= threshold)2049return r % bound;2050}2051}20522053#if PCG_HAS_128BIT_OPS2054static inline uint64_t pcg_mcg_128_rxs_m_64_random_r(struct pcg_state_128* rng)2055{2056pcg_mcg_128_step_r(rng);2057return pcg_output_rxs_m_128_64(rng->state);2058}2059#endif20602061#if PCG_HAS_128BIT_OPS2062static inline uint64_t pcg_mcg_128_rxs_m_64_boundedrand_r(struct pcg_state_128* rng,2063uint64_t bound)2064{2065uint64_t threshold = -bound % bound;2066for (;;) {2067uint64_t r = pcg_mcg_128_rxs_m_64_random_r(rng);2068if (r >= threshold)2069return r % bound;2070}2071}2072#endif20732074/* Generation functions for XSL RR (only defined for "large" types) */20752076static inline uint32_t pcg_oneseq_64_xsl_rr_32_random_r(struct pcg_state_64* rng)2077{2078uint64_t oldstate = rng->state;2079pcg_oneseq_64_step_r(rng);2080return pcg_output_xsl_rr_64_32(oldstate);2081}20822083static inline uint32_t pcg_oneseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng,2084uint32_t bound)2085{2086uint32_t threshold = -bound % bound;2087for (;;) {2088uint32_t r = pcg_oneseq_64_xsl_rr_32_random_r(rng);2089if (r >= threshold)2090return r % bound;2091}2092}20932094#if PCG_HAS_128BIT_OPS2095static inline uint64_t pcg_oneseq_128_xsl_rr_64_random_r(struct pcg_state_128* rng)2096{2097pcg_oneseq_128_step_r(rng);2098return pcg_output_xsl_rr_128_64(rng->state);2099}2100#endif21012102#if PCG_HAS_128BIT_OPS2103static inline uint64_t2104pcg_oneseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,2105uint64_t bound)2106{2107uint64_t threshold = -bound % bound;2108for (;;) {2109uint64_t r = pcg_oneseq_128_xsl_rr_64_random_r(rng);2110if (r >= threshold)2111return r % bound;2112}2113}2114#endif21152116static inline uint32_t pcg_unique_64_xsl_rr_32_random_r(struct pcg_state_64* rng)2117{2118uint64_t oldstate = rng->state;2119pcg_unique_64_step_r(rng);2120return pcg_output_xsl_rr_64_32(oldstate);2121}21222123static inline uint32_t pcg_unique_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng,2124uint32_t bound)2125{2126uint32_t threshold = -bound % bound;2127for (;;) {2128uint32_t r = pcg_unique_64_xsl_rr_32_random_r(rng);2129if (r >= threshold)2130return r % bound;2131}2132}21332134#if PCG_HAS_128BIT_OPS2135static inline uint64_t pcg_unique_128_xsl_rr_64_random_r(struct pcg_state_128* rng)2136{2137pcg_unique_128_step_r(rng);2138return pcg_output_xsl_rr_128_64(rng->state);2139}2140#endif21412142#if PCG_HAS_128BIT_OPS2143static inline uint64_t2144pcg_unique_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,2145uint64_t bound)2146{2147uint64_t threshold = -bound % bound;2148for (;;) {2149uint64_t r = pcg_unique_128_xsl_rr_64_random_r(rng);2150if (r >= threshold)2151return r % bound;2152}2153}2154#endif21552156static inline uint32_t2157pcg_setseq_64_xsl_rr_32_random_r(struct pcg_state_setseq_64* rng)2158{2159uint64_t oldstate = rng->state;2160pcg_setseq_64_step_r(rng);2161return pcg_output_xsl_rr_64_32(oldstate);2162}21632164static inline uint32_t2165pcg_setseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng,2166uint32_t bound)2167{2168uint32_t threshold = -bound % bound;2169for (;;) {2170uint32_t r = pcg_setseq_64_xsl_rr_32_random_r(rng);2171if (r >= threshold)2172return r % bound;2173}2174}21752176#if PCG_HAS_128BIT_OPS2177static inline uint64_t2178pcg_setseq_128_xsl_rr_64_random_r(struct pcg_state_setseq_128* rng)2179{2180pcg_setseq_128_step_r(rng);2181return pcg_output_xsl_rr_128_64(rng->state);2182}2183#endif21842185#if PCG_HAS_128BIT_OPS2186static inline uint64_t2187pcg_setseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng,2188uint64_t bound)2189{2190uint64_t threshold = -bound % bound;2191for (;;) {2192uint64_t r = pcg_setseq_128_xsl_rr_64_random_r(rng);2193if (r >= threshold)2194return r % bound;2195}2196}2197#endif21982199static inline uint32_t pcg_mcg_64_xsl_rr_32_random_r(struct pcg_state_64* rng)2200{2201uint64_t oldstate = rng->state;2202pcg_mcg_64_step_r(rng);2203return pcg_output_xsl_rr_64_32(oldstate);2204}22052206static inline uint32_t pcg_mcg_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng,2207uint32_t bound)2208{2209uint32_t threshold = -bound % bound;2210for (;;) {2211uint32_t r = pcg_mcg_64_xsl_rr_32_random_r(rng);2212if (r >= threshold)2213return r % bound;2214}2215}22162217#if PCG_HAS_128BIT_OPS2218static inline uint64_t pcg_mcg_128_xsl_rr_64_random_r(struct pcg_state_128* rng)2219{2220pcg_mcg_128_step_r(rng);2221return pcg_output_xsl_rr_128_64(rng->state);2222}2223#endif22242225#if PCG_HAS_128BIT_OPS2226static inline uint64_t pcg_mcg_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,2227uint64_t bound)2228{2229uint64_t threshold = -bound % bound;2230for (;;) {2231uint64_t r = pcg_mcg_128_xsl_rr_64_random_r(rng);2232if (r >= threshold)2233return r % bound;2234}2235}2236#endif22372238/* Generation functions for XSL RR RR (only defined for "large" types) */22392240static inline uint64_t pcg_oneseq_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng)2241{2242uint64_t oldstate = rng->state;2243pcg_oneseq_64_step_r(rng);2244return pcg_output_xsl_rr_rr_64_64(oldstate);2245}22462247static inline uint64_t2248pcg_oneseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng,2249uint64_t bound)2250{2251uint64_t threshold = -bound % bound;2252for (;;) {2253uint64_t r = pcg_oneseq_64_xsl_rr_rr_64_random_r(rng);2254if (r >= threshold)2255return r % bound;2256}2257}22582259#if PCG_HAS_128BIT_OPS2260static inline pcg128_t pcg_oneseq_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng)2261{2262pcg_oneseq_128_step_r(rng);2263return pcg_output_xsl_rr_rr_128_128(rng->state);2264}2265#endif22662267#if PCG_HAS_128BIT_OPS2268static inline pcg128_t2269pcg_oneseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng,2270pcg128_t bound)2271{2272pcg128_t threshold = -bound % bound;2273for (;;) {2274pcg128_t r = pcg_oneseq_128_xsl_rr_rr_128_random_r(rng);2275if (r >= threshold)2276return r % bound;2277}2278}2279#endif22802281static inline uint64_t pcg_unique_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng)2282{2283uint64_t oldstate = rng->state;2284pcg_unique_64_step_r(rng);2285return pcg_output_xsl_rr_rr_64_64(oldstate);2286}22872288static inline uint64_t2289pcg_unique_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng,2290uint64_t bound)2291{2292uint64_t threshold = -bound % bound;2293for (;;) {2294uint64_t r = pcg_unique_64_xsl_rr_rr_64_random_r(rng);2295if (r >= threshold)2296return r % bound;2297}2298}22992300#if PCG_HAS_128BIT_OPS2301static inline pcg128_t pcg_unique_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng)2302{2303pcg_unique_128_step_r(rng);2304return pcg_output_xsl_rr_rr_128_128(rng->state);2305}2306#endif23072308#if PCG_HAS_128BIT_OPS2309static inline pcg128_t2310pcg_unique_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng,2311pcg128_t bound)2312{2313pcg128_t threshold = -bound % bound;2314for (;;) {2315pcg128_t r = pcg_unique_128_xsl_rr_rr_128_random_r(rng);2316if (r >= threshold)2317return r % bound;2318}2319}2320#endif23212322static inline uint64_t2323pcg_setseq_64_xsl_rr_rr_64_random_r(struct pcg_state_setseq_64* rng)2324{2325uint64_t oldstate = rng->state;2326pcg_setseq_64_step_r(rng);2327return pcg_output_xsl_rr_rr_64_64(oldstate);2328}23292330static inline uint64_t2331pcg_setseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_setseq_64* rng,2332uint64_t bound)2333{2334uint64_t threshold = -bound % bound;2335for (;;) {2336uint64_t r = pcg_setseq_64_xsl_rr_rr_64_random_r(rng);2337if (r >= threshold)2338return r % bound;2339}2340}23412342#if PCG_HAS_128BIT_OPS2343static inline pcg128_t2344pcg_setseq_128_xsl_rr_rr_128_random_r(struct pcg_state_setseq_128* rng)2345{2346pcg_setseq_128_step_r(rng);2347return pcg_output_xsl_rr_rr_128_128(rng->state);2348}2349#endif23502351#if PCG_HAS_128BIT_OPS2352static inline pcg128_t2353pcg_setseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_setseq_128* rng,2354pcg128_t bound)2355{2356pcg128_t threshold = -bound % bound;2357for (;;) {2358pcg128_t r = pcg_setseq_128_xsl_rr_rr_128_random_r(rng);2359if (r >= threshold)2360return r % bound;2361}2362}2363#endif23642365/*** Typedefs */2366typedef struct pcg_state_setseq_64 pcg32_random_t;2367typedef struct pcg_state_64 pcg32s_random_t;2368typedef struct pcg_state_64 pcg32u_random_t;2369typedef struct pcg_state_64 pcg32f_random_t;2370/*** random_r */2371#define pcg32_random_r pcg_setseq_64_xsh_rr_32_random_r2372#define pcg32s_random_r pcg_oneseq_64_xsh_rr_32_random_r2373#define pcg32u_random_r pcg_unique_64_xsh_rr_32_random_r2374#define pcg32f_random_r pcg_mcg_64_xsh_rs_32_random_r2375/*** boundedrand_r */2376#define pcg32_boundedrand_r pcg_setseq_64_xsh_rr_32_boundedrand_r2377#define pcg32s_boundedrand_r pcg_oneseq_64_xsh_rr_32_boundedrand_r2378#define pcg32u_boundedrand_r pcg_unique_64_xsh_rr_32_boundedrand_r2379#define pcg32f_boundedrand_r pcg_mcg_64_xsh_rs_32_boundedrand_r2380/*** srandom_r */2381#define pcg32_srandom_r pcg_setseq_64_srandom_r2382#define pcg32s_srandom_r pcg_oneseq_64_srandom_r2383#define pcg32u_srandom_r pcg_unique_64_srandom_r2384#define pcg32f_srandom_r pcg_mcg_64_srandom_r2385/*** advance_r */2386#define pcg32_advance_r pcg_setseq_64_advance_r2387#define pcg32s_advance_r pcg_oneseq_64_advance_r2388#define pcg32u_advance_r pcg_unique_64_advance_r2389#define pcg32f_advance_r pcg_mcg_64_advance_r23902391#if PCG_HAS_128BIT_OPS2392/*** Typedefs */2393typedef struct pcg_state_setseq_128 pcg64_random_t;2394typedef struct pcg_state_128 pcg64s_random_t;2395typedef struct pcg_state_128 pcg64u_random_t;2396typedef struct pcg_state_128 pcg64f_random_t;2397/*** random_r */2398#define pcg64_random_r pcg_setseq_128_xsl_rr_64_random_r2399#define pcg64s_random_r pcg_oneseq_128_xsl_rr_64_random_r2400#define pcg64u_random_r pcg_unique_128_xsl_rr_64_random_r2401#define pcg64f_random_r pcg_mcg_128_xsl_rr_64_random_r2402/*** boundedrand_r */2403#define pcg64_boundedrand_r pcg_setseq_128_xsl_rr_64_boundedrand_r2404#define pcg64s_boundedrand_r pcg_oneseq_128_xsl_rr_64_boundedrand_r2405#define pcg64u_boundedrand_r pcg_unique_128_xsl_rr_64_boundedrand_r2406#define pcg64f_boundedrand_r pcg_mcg_128_xsl_rr_64_boundedrand_r2407/*** srandom_r */2408#define pcg64_srandom_r pcg_setseq_128_srandom_r2409#define pcg64s_srandom_r pcg_oneseq_128_srandom_r2410#define pcg64u_srandom_r pcg_unique_128_srandom_r2411#define pcg64f_srandom_r pcg_mcg_128_srandom_r2412/*** advance_r */2413#define pcg64_advance_r pcg_setseq_128_advance_r2414#define pcg64s_advance_r pcg_oneseq_128_advance_r2415#define pcg64u_advance_r pcg_unique_128_advance_r2416#define pcg64f_advance_r pcg_mcg_128_advance_r2417#endif24182419/*** Typedefs */2420typedef struct pcg_state_8 pcg8si_random_t;2421typedef struct pcg_state_16 pcg16si_random_t;2422typedef struct pcg_state_32 pcg32si_random_t;2423typedef struct pcg_state_64 pcg64si_random_t;2424/*** random_r */2425#define pcg8si_random_r pcg_oneseq_8_rxs_m_xs_8_random_r2426#define pcg16si_random_r pcg_oneseq_16_rxs_m_xs_16_random_r2427#define pcg32si_random_r pcg_oneseq_32_rxs_m_xs_32_random_r2428#define pcg64si_random_r pcg_oneseq_64_rxs_m_xs_64_random_r2429/*** boundedrand_r */2430#define pcg8si_boundedrand_r pcg_oneseq_8_rxs_m_xs_8_boundedrand_r2431#define pcg16si_boundedrand_r pcg_oneseq_16_rxs_m_xs_16_boundedrand_r2432#define pcg32si_boundedrand_r pcg_oneseq_32_rxs_m_xs_32_boundedrand_r2433#define pcg64si_boundedrand_r pcg_oneseq_64_rxs_m_xs_64_boundedrand_r2434/*** srandom_r */2435#define pcg8si_srandom_r pcg_oneseq_8_srandom_r2436#define pcg16si_srandom_r pcg_oneseq_16_srandom_r2437#define pcg32si_srandom_r pcg_oneseq_32_srandom_r2438#define pcg64si_srandom_r pcg_oneseq_64_srandom_r2439/*** advance_r */2440#define pcg8si_advance_r pcg_oneseq_8_advance_r2441#define pcg16si_advance_r pcg_oneseq_16_advance_r2442#define pcg32si_advance_r pcg_oneseq_32_advance_r2443#define pcg64si_advance_r pcg_oneseq_64_advance_r24442445#if PCG_HAS_128BIT_OPS2446typedef struct pcg_state_128 pcg128si_random_t;2447#define pcg128si_random_r pcg_oneseq_128_rxs_m_xs_128_random_r2448#define pcg128si_boundedrand_r pcg_oneseq_128_rxs_m_xs_128_boundedrand_r2449#define pcg128si_srandom_r pcg_oneseq_128_srandom_r2450#define pcg128si_advance_r pcg_oneseq_128_advance_r2451#endif24522453/*** Typedefs */2454typedef struct pcg_state_setseq_8 pcg8i_random_t;2455typedef struct pcg_state_setseq_16 pcg16i_random_t;2456typedef struct pcg_state_setseq_32 pcg32i_random_t;2457typedef struct pcg_state_setseq_64 pcg64i_random_t;2458/*** random_r */2459#define pcg8i_random_r pcg_setseq_8_rxs_m_xs_8_random_r2460#define pcg16i_random_r pcg_setseq_16_rxs_m_xs_16_random_r2461#define pcg32i_random_r pcg_setseq_32_rxs_m_xs_32_random_r2462#define pcg64i_random_r pcg_setseq_64_rxs_m_xs_64_random_r2463/*** boundedrand_r */2464#define pcg8i_boundedrand_r pcg_setseq_8_rxs_m_xs_8_boundedrand_r2465#define pcg16i_boundedrand_r pcg_setseq_16_rxs_m_xs_16_boundedrand_r2466#define pcg32i_boundedrand_r pcg_setseq_32_rxs_m_xs_32_boundedrand_r2467#define pcg64i_boundedrand_r pcg_setseq_64_rxs_m_xs_64_boundedrand_r2468/*** srandom_r */2469#define pcg8i_srandom_r pcg_setseq_8_srandom_r2470#define pcg16i_srandom_r pcg_setseq_16_srandom_r2471#define pcg32i_srandom_r pcg_setseq_32_srandom_r2472#define pcg64i_srandom_r pcg_setseq_64_srandom_r2473/*** advance_r */2474#define pcg8i_advance_r pcg_setseq_8_advance_r2475#define pcg16i_advance_r pcg_setseq_16_advance_r2476#define pcg32i_advance_r pcg_setseq_32_advance_r2477#define pcg64i_advance_r pcg_setseq_64_advance_r24782479#if PCG_HAS_128BIT_OPS2480typedef struct pcg_state_setseq_128 pcg128i_random_t;2481#define pcg128i_random_r pcg_setseq_128_rxs_m_xs_128_random_r2482#define pcg128i_boundedrand_r pcg_setseq_128_rxs_m_xs_128_boundedrand_r2483#define pcg128i_srandom_r pcg_setseq_128_srandom_r2484#define pcg128i_advance_r pcg_setseq_128_advance_r2485#endif24862487/*2488* Static initialization constants (if you can't call srandom for some2489* bizarre reason).2490*/24912492#define PCG32_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER2493#define PCG32U_INITIALIZER PCG_STATE_UNIQUE_64_INITIALIZER2494#define PCG32S_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER2495#define PCG32F_INITIALIZER PCG_STATE_MCG_64_INITIALIZER24962497#if PCG_HAS_128BIT_OPS2498#define PCG64_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER2499#define PCG64U_INITIALIZER PCG_STATE_UNIQUE_128_INITIALIZER2500#define PCG64S_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER2501#define PCG64F_INITIALIZER PCG_STATE_MCG_128_INITIALIZER2502#endif25032504#define PCG8SI_INITIALIZER PCG_STATE_ONESEQ_8_INITIALIZER2505#define PCG16SI_INITIALIZER PCG_STATE_ONESEQ_16_INITIALIZER2506#define PCG32SI_INITIALIZER PCG_STATE_ONESEQ_32_INITIALIZER2507#define PCG64SI_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER2508#if PCG_HAS_128BIT_OPS2509#define PCG128SI_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER2510#endif25112512#define PCG8I_INITIALIZER PCG_STATE_SETSEQ_8_INITIALIZER2513#define PCG16I_INITIALIZER PCG_STATE_SETSEQ_16_INITIALIZER2514#define PCG32I_INITIALIZER PCG_STATE_SETSEQ_32_INITIALIZER2515#define PCG64I_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER2516#if PCG_HAS_128BIT_OPS2517#define PCG128I_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER2518#endif25192520#ifdef __cplusplus2521}2522#endif25232524#endif /* PCG_VARIANTS_H_INCLUDED */2525252625272528