summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/haversine/build.sh36
-rw-r--r--src/haversine/haversine_generator.cpp138
-rw-r--r--src/haversine/haversine_random.h107
l---------src/haversine/libs/lr/lr.h1
l---------src/haversine/libs/lr/lr_macros.h1
l---------src/haversine/libs/lr/lr_platform.h1
l---------src/haversine/libs/lr/lr_types.h1
-rw-r--r--src/haversine/libs/pcg/pcg-advance-128.c64
-rw-r--r--src/haversine/libs/pcg/pcg-advance-16.c62
-rw-r--r--src/haversine/libs/pcg/pcg-advance-32.c62
-rw-r--r--src/haversine/libs/pcg/pcg-advance-64.c62
-rw-r--r--src/haversine/libs/pcg/pcg-advance-8.c62
-rw-r--r--src/haversine/libs/pcg/pcg-global-32.c56
-rw-r--r--src/haversine/libs/pcg/pcg-global-64.c59
-rw-r--r--src/haversine/libs/pcg/pcg-output-128.c64
-rw-r--r--src/haversine/libs/pcg/pcg-output-16.c60
-rw-r--r--src/haversine/libs/pcg/pcg-output-32.c62
-rw-r--r--src/haversine/libs/pcg/pcg-output-64.c70
-rw-r--r--src/haversine/libs/pcg/pcg-output-8.c60
-rw-r--r--src/haversine/libs/pcg/pcg-rngs-128.c337
-rw-r--r--src/haversine/libs/pcg/pcg-rngs-16.c183
-rw-r--r--src/haversine/libs/pcg/pcg-rngs-32.c187
-rw-r--r--src/haversine/libs/pcg/pcg-rngs-64.c232
-rw-r--r--src/haversine/libs/pcg/pcg-rngs-8.c128
-rw-r--r--src/haversine/libs/pcg/pcg.c16
-rw-r--r--src/haversine/libs/pcg/pcg_variants.h2213
-rw-r--r--src/haversine/listing_065.cpp39
-rw-r--r--src/sim86/bin/generated/generated.cpp0
-rwxr-xr-xsrc/sim86/bin/tmux.sh (renamed from src/tmux.sh)0
-rwxr-xr-xsrc/sim86/build.sh (renamed from src/build.sh)13
-rw-r--r--src/sim86/clocks_table.inl (renamed from src/clocks_table.inl)0
-rw-r--r--src/sim86/generated/generated.cpp (renamed from src/generated/generated.cpp)0
-rw-r--r--src/sim86/libs/metadesk/md.c (renamed from src/libs/metadesk/md.c)0
-rw-r--r--src/sim86/libs/metadesk/md.h (renamed from src/libs/metadesk/md.h)0
-rw-r--r--src/sim86/libs/metadesk/md_stb_sprintf.h (renamed from src/libs/metadesk/md_stb_sprintf.h)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86.h (renamed from src/libs/reference_decoder/sim86.h)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_decode.cpp (renamed from src/libs/reference_decoder/sim86_decode.cpp)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_decode.h (renamed from src/libs/reference_decoder/sim86_decode.h)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_instruction.cpp (renamed from src/libs/reference_decoder/sim86_instruction.cpp)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_instruction.h (renamed from src/libs/reference_decoder/sim86_instruction.h)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_instruction_table.cpp (renamed from src/libs/reference_decoder/sim86_instruction_table.cpp)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_instruction_table.h (renamed from src/libs/reference_decoder/sim86_instruction_table.h)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_instruction_table.inl (renamed from src/libs/reference_decoder/sim86_instruction_table.inl)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_lib.cpp (renamed from src/libs/reference_decoder/sim86_lib.cpp)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_memory.cpp (renamed from src/libs/reference_decoder/sim86_memory.cpp)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_memory.h (renamed from src/libs/reference_decoder/sim86_memory.h)0
-rw-r--r--src/sim86/libs/reference_decoder/sim86_text_table.cpp (renamed from src/libs/reference_decoder/sim86_text_table.cpp)0
-rw-r--r--src/sim86/sim86.cpp (renamed from src/sim86.cpp)0
-rw-r--r--src/sim86/sim86.h (renamed from src/sim86.h)0
-rw-r--r--src/sim86/sim86.mdesk (renamed from src/sim86.mdesk)0
-rw-r--r--src/sim86/sim86_meta.c (renamed from src/sim86_meta.c)1
-rw-r--r--src/sim86/sim86_shared.h (renamed from src/sim86_shared.h)0
52 files changed, 4371 insertions, 6 deletions
diff --git a/src/haversine/build.sh b/src/haversine/build.sh
new file mode 100755
index 0000000..38170c0
--- /dev/null
+++ b/src/haversine/build.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+cd "$(dirname "$(readlink -f "$0")")"
+
+Build="../../build"
+mkdir -p "$Build"
+mkdir -p generated
+
+Compiler="clang"
+
+CompilerFlags="
+-g
+-fdiagnostics-absolute-paths
+-nostdinc++
+"
+
+WarningFlags="
+-Wall
+-Wextra
+-Wno-unused-label
+-Wno-unused-variable
+-Wno-unused-function
+-Wno-unused-value
+-Wno-unused-but-set-variable
+-Wno-missing-field-initializers
+-Wno-write-strings
+-Wno-unused-parameter
+"
+
+LinkerFlags="-lm"
+
+printf '[debug mode]\n'
+printf '[%s build]\n' "$Compiler"
+$Compiler $CompilerFlags $WarningFlags $LinkerFlags \
+ -o "$Build"/haversine_generator \
+ haversine_generator.cpp \ No newline at end of file
diff --git a/src/haversine/haversine_generator.cpp b/src/haversine/haversine_generator.cpp
new file mode 100644
index 0000000..c3f7561
--- /dev/null
+++ b/src/haversine/haversine_generator.cpp
@@ -0,0 +1,138 @@
+#include "libs/lr/lr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#define MemoryCopy memcpy
+
+#include "listing_065.cpp"
+
+#include "haversine_random.h"
+
+enum generation_method : u32
+{
+ Method_Uniform,
+ Method_Cluster
+};
+
+int main(int ArgsCount, char *Args[], char *Env[])
+{
+ // 1. haversine_generator [uniform/cluster] [random seed] [number of pairs to generate]
+
+ if(ArgsCount >= 4)
+ {
+ u32 Method = 0;
+ u64 RandomSeed = 0;;
+ u64 PairsCount = 0;
+ b32 Error = false;
+
+ if(!strcmp(Args[1], "uniform"))
+ {
+ Method = Method_Uniform;
+ }
+ else if(!strcmp(Args[1], "cluster"))
+ {
+ Method = Method_Cluster;
+ }
+ else
+ {
+ Error = true;
+ }
+
+ RandomSeed = atoll(Args[2]);
+
+ if(RandomSeed == 0)
+ {
+ if(Args[2][0] == '0')
+ {
+ RandomSeed = 0;
+ }
+ else
+ {
+ Error = true;
+ }
+ }
+
+ PairsCount = atoll(Args[3]);
+ if(PairsCount == 0)
+ {
+ Error = true;
+ }
+
+ if(!Error)
+ {
+ printf("Method: %s\n"
+ "Random seed: %lu\n"
+ "Pairs count: %lu\n"
+ , Args[1], RandomSeed, PairsCount);
+
+ // Generate pairs in the following format.
+ //
+ // {
+ // "pairs":
+ // [
+ // { "x0": ..., "y0": ..., "x1": ..., "y1": ... },
+ // { "x0": ..., "y0": ..., "x1": ..., "y1": ... }
+ // ]
+ // }
+ //
+
+ FILE *Out = fopen("out.json", "wb");
+ char *JsonHeader =
+ "{\n"
+ " \"pairs\":\n"
+ " [\n";
+ char *JsonFooter =
+ " ]\n"
+ "}\n";
+
+ fprintf(Out, "%s", JsonHeader);
+
+ pcg64_random_t RNG = {};
+ pcg64_srandom_r(&RNG, RandomSeed, RandomSeed);
+
+ f64 AverageSum = 0;
+ f64 TotalSum = 0;
+ for(u64 PairsIndex = 0;
+ PairsIndex < PairsCount;
+ PairsIndex++)
+ {
+ b32 LastPair = false;
+
+ f64 X0 = RandomBetween(&RNG, -180.0, 180.0);
+ f64 Y0 = RandomBetween(&RNG, -360.0, 360.0);
+ f64 X1 = RandomBetween(&RNG, -180.0, 180.0);
+ f64 Y1 = RandomBetween(&RNG, -360.0, 360.0);
+
+ f64 Sum = ReferenceHaversine(X0, Y0, X1, Y1, 6372.8);
+ TotalSum += Sum;
+
+ // NOTE(luca): A double's mantissa is 52 bits. 2^52 - 1 is 4503599627370495 which has
+ // 16 digits.
+ fprintf(Out,
+ " { \"x0\": %.15f, \"y0\": %.15f, \"x1\": %.15f, \"y1\": %.15f }\n",
+ X0, Y0, X1, Y1);
+
+ }
+ AverageSum = TotalSum / (f64)PairsCount;
+
+ fprintf(Out, "%s", JsonFooter);
+
+ printf("Average sum: %f\n", AverageSum);
+ }
+ else
+ {
+ printf("Usage: %s [uniform/cluster] [random seed] [number of pairs to generate]\n",
+ Args[0]);
+ }
+ }
+ else
+ {
+ printf("Usage: %s [uniform/cluster] [random seed] [number of pairs to generate]\n",
+ Args[0]);
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/src/haversine/haversine_random.h b/src/haversine/haversine_random.h
new file mode 100644
index 0000000..b7c545e
--- /dev/null
+++ b/src/haversine/haversine_random.h
@@ -0,0 +1,107 @@
+
+#include <math.h>
+
+#include "libs/pcg/pcg.c"
+
+#define CountLeadingZeroes64(Value) __builtin_clzll(Value)
+
+u64
+RandomU64(pcg64_random_t *RNG)
+{
+ u64 Result = pcg64_random_r(RNG);
+ return Result;
+}
+
+//~ Random 64 bit float
+
+// From: https://mumble.net/~campbell/tmp/random_real.c
+/*
+ * Copyright (c) 2014, Taylor R Campbell
+*
+* Verbatim copying and distribution of this entire article are
+* permitted worldwide, without royalty, in any medium, provided
+* this notice, and the copyright notice, are preserved.
+*
+*/
+
+/*
+ * random_real: Generate a stream of bits uniformly at random and
+ * interpret it as the fractional part of the binary expansion of a
+ * number in [0, 1], 0.00001010011111010100...; then round it.
+ */
+f64
+RandomF64(pcg64_random_t *RNG)
+{
+ s32 Exponent = -64;
+ u64 Significand;
+ umm Shift;
+
+ /*
+ * Read zeros into the exponent until we hit a one; the rest
+ * will go into the significand.
+ */
+ while((Significand = RandomU64(RNG)) == 0)
+ {
+ Exponent -= 64;
+ /*
+ * If the exponent falls below -1074 = emin + 1 - p,
+ * the exponent of the smallest subnormal, we are
+ * guaranteed the result will be rounded to zero. This
+ * case is so unlikely it will happen in realistic
+ * terms only if RandomU64 is broken.
+ */
+ if ((Exponent < -1074))
+ return 0;
+ }
+
+ /*
+ * There is a 1 somewhere in significand, not necessarily in
+ * the most significant position. If there are leading zeros,
+ * shift them into the exponent and refill the less-significant
+ * bits of the significand. Can't predict one way or another
+ * whether there are leading zeros: there's a fifty-fifty
+ * chance, if RandomU64() is uniformly distributed.
+ */
+ Shift = CountLeadingZeroes64(Significand);
+ if (Shift != 0) {
+ Exponent -= Shift;
+ Significand <<= Shift;
+ Significand |= (RandomU64(RNG) >> (64 - Shift));
+ }
+
+ /*
+ * Set the sticky bit, since there is almost surely another 1
+ * in the bit stream. Otherwise, we might round what looks
+ * like a tie to even when, almost surely, were we to look
+ * further in the bit stream, there would be a 1 breaking the
+ * tie.
+ */
+ Significand |= 1;
+
+ /*
+ * Finally, convert to f64 (rounding) and scale by
+ * 2^exponent.
+ */
+ return ldexp((f64)Significand, Exponent);
+}
+
+f64
+RandomUnilateral(pcg64_random_t *RNG)
+{
+ return RandomF64(RNG);
+}
+
+f64
+RandomBilateral(pcg64_random_t *RNG)
+{
+ f64 Result = 2.0*RandomUnilateral(RNG) - 1.0;
+ return Result;
+}
+
+f64
+RandomBetween(pcg64_random_t *RNG, f64 Min, f64 Max)
+{
+ f64 Range = Max - Min;
+ f64 Result = Min + RandomUnilateral(RNG)*Range;
+ return Result;
+} \ No newline at end of file
diff --git a/src/haversine/libs/lr/lr.h b/src/haversine/libs/lr/lr.h
new file mode 120000
index 0000000..49fb375
--- /dev/null
+++ b/src/haversine/libs/lr/lr.h
@@ -0,0 +1 @@
+/home/aluc/proj/lr/lr.h \ No newline at end of file
diff --git a/src/haversine/libs/lr/lr_macros.h b/src/haversine/libs/lr/lr_macros.h
new file mode 120000
index 0000000..530249a
--- /dev/null
+++ b/src/haversine/libs/lr/lr_macros.h
@@ -0,0 +1 @@
+/home/aluc/proj/lr/lr_macros.h \ No newline at end of file
diff --git a/src/haversine/libs/lr/lr_platform.h b/src/haversine/libs/lr/lr_platform.h
new file mode 120000
index 0000000..e387ee2
--- /dev/null
+++ b/src/haversine/libs/lr/lr_platform.h
@@ -0,0 +1 @@
+/home/aluc/proj/lr/lr_platform.h \ No newline at end of file
diff --git a/src/haversine/libs/lr/lr_types.h b/src/haversine/libs/lr/lr_types.h
new file mode 120000
index 0000000..6d2fa08
--- /dev/null
+++ b/src/haversine/libs/lr/lr_types.h
@@ -0,0 +1 @@
+/home/aluc/proj/lr/lr_types.h \ No newline at end of file
diff --git a/src/haversine/libs/pcg/pcg-advance-128.c b/src/haversine/libs/pcg/pcg-advance-128.c
new file mode 100644
index 0000000..be72009
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-advance-128.c
@@ -0,0 +1,64 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * Repetative C code is derived using C preprocessor metaprogramming
+ * techniques.
+ */
+
+#include "pcg_variants.h"
+
+/* Multi-step advance functions (jump-ahead, jump-back)
+ *
+ * The method used here is based on Brown, "Random Number Generation
+ * with Arbitrary Stride,", Transactions of the American Nuclear
+ * Society (Nov. 1994). The algorithm is very similar to fast
+ * exponentiation.
+ *
+ * Even though delta is an unsigned integer, we can pass a
+ * signed integer to go backwards, it just goes "the long way round".
+ */
+
+#if PCG_HAS_128BIT_OPS
+pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta, pcg128_t cur_mult,
+ pcg128_t cur_plus)
+{
+ pcg128_t acc_mult = 1u;
+ pcg128_t acc_plus = 0u;
+ while (delta > 0) {
+ if (delta & 1) {
+ acc_mult *= cur_mult;
+ acc_plus = acc_plus * cur_mult + cur_plus;
+ }
+ cur_plus = (cur_mult + 1) * cur_plus;
+ cur_mult *= cur_mult;
+ delta /= 2;
+ }
+ return acc_mult * state + acc_plus;
+}
+#endif
+
diff --git a/src/haversine/libs/pcg/pcg-advance-16.c b/src/haversine/libs/pcg/pcg-advance-16.c
new file mode 100644
index 0000000..11461d9
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-advance-16.c
@@ -0,0 +1,62 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * Repetative C code is derived using C preprocessor metaprogramming
+ * techniques.
+ */
+
+#include "pcg_variants.h"
+
+/* Multi-step advance functions (jump-ahead, jump-back)
+ *
+ * The method used here is based on Brown, "Random Number Generation
+ * with Arbitrary Stride,", Transactions of the American Nuclear
+ * Society (Nov. 1994). The algorithm is very similar to fast
+ * exponentiation.
+ *
+ * Even though delta is an unsigned integer, we can pass a
+ * signed integer to go backwards, it just goes "the long way round".
+ */
+
+uint16_t pcg_advance_lcg_16(uint16_t state, uint16_t delta, uint16_t cur_mult,
+ uint16_t cur_plus)
+{
+ uint16_t acc_mult = 1u;
+ uint16_t acc_plus = 0u;
+ while (delta > 0) {
+ if (delta & 1) {
+ acc_mult *= cur_mult;
+ acc_plus = acc_plus * cur_mult + cur_plus;
+ }
+ cur_plus = (cur_mult + 1) * cur_plus;
+ cur_mult *= cur_mult;
+ delta /= 2;
+ }
+ return acc_mult * state + acc_plus;
+}
+
diff --git a/src/haversine/libs/pcg/pcg-advance-32.c b/src/haversine/libs/pcg/pcg-advance-32.c
new file mode 100644
index 0000000..76f35fc
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-advance-32.c
@@ -0,0 +1,62 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * Repetative C code is derived using C preprocessor metaprogramming
+ * techniques.
+ */
+
+#include "pcg_variants.h"
+
+/* Multi-step advance functions (jump-ahead, jump-back)
+ *
+ * The method used here is based on Brown, "Random Number Generation
+ * with Arbitrary Stride,", Transactions of the American Nuclear
+ * Society (Nov. 1994). The algorithm is very similar to fast
+ * exponentiation.
+ *
+ * Even though delta is an unsigned integer, we can pass a
+ * signed integer to go backwards, it just goes "the long way round".
+ */
+
+uint32_t pcg_advance_lcg_32(uint32_t state, uint32_t delta, uint32_t cur_mult,
+ uint32_t cur_plus)
+{
+ uint32_t acc_mult = 1u;
+ uint32_t acc_plus = 0u;
+ while (delta > 0) {
+ if (delta & 1) {
+ acc_mult *= cur_mult;
+ acc_plus = acc_plus * cur_mult + cur_plus;
+ }
+ cur_plus = (cur_mult + 1) * cur_plus;
+ cur_mult *= cur_mult;
+ delta /= 2;
+ }
+ return acc_mult * state + acc_plus;
+}
+
diff --git a/src/haversine/libs/pcg/pcg-advance-64.c b/src/haversine/libs/pcg/pcg-advance-64.c
new file mode 100644
index 0000000..8210e75
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-advance-64.c
@@ -0,0 +1,62 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * Repetative C code is derived using C preprocessor metaprogramming
+ * techniques.
+ */
+
+#include "pcg_variants.h"
+
+/* Multi-step advance functions (jump-ahead, jump-back)
+ *
+ * The method used here is based on Brown, "Random Number Generation
+ * with Arbitrary Stride,", Transactions of the American Nuclear
+ * Society (Nov. 1994). The algorithm is very similar to fast
+ * exponentiation.
+ *
+ * Even though delta is an unsigned integer, we can pass a
+ * signed integer to go backwards, it just goes "the long way round".
+ */
+
+uint64_t pcg_advance_lcg_64(uint64_t state, uint64_t delta, uint64_t cur_mult,
+ uint64_t cur_plus)
+{
+ uint64_t acc_mult = 1u;
+ uint64_t acc_plus = 0u;
+ while (delta > 0) {
+ if (delta & 1) {
+ acc_mult *= cur_mult;
+ acc_plus = acc_plus * cur_mult + cur_plus;
+ }
+ cur_plus = (cur_mult + 1) * cur_plus;
+ cur_mult *= cur_mult;
+ delta /= 2;
+ }
+ return acc_mult * state + acc_plus;
+}
+
diff --git a/src/haversine/libs/pcg/pcg-advance-8.c b/src/haversine/libs/pcg/pcg-advance-8.c
new file mode 100644
index 0000000..8280958
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-advance-8.c
@@ -0,0 +1,62 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * Repetative C code is derived using C preprocessor metaprogramming
+ * techniques.
+ */
+
+#include "pcg_variants.h"
+
+/* Multi-step advance functions (jump-ahead, jump-back)
+ *
+ * The method used here is based on Brown, "Random Number Generation
+ * with Arbitrary Stride,", Transactions of the American Nuclear
+ * Society (Nov. 1994). The algorithm is very similar to fast
+ * exponentiation.
+ *
+ * Even though delta is an unsigned integer, we can pass a
+ * signed integer to go backwards, it just goes "the long way round".
+ */
+
+uint8_t pcg_advance_lcg_8(uint8_t state, uint8_t delta, uint8_t cur_mult,
+ uint8_t cur_plus)
+{
+ uint8_t acc_mult = 1u;
+ uint8_t acc_plus = 0u;
+ while (delta > 0) {
+ if (delta & 1) {
+ acc_mult *= cur_mult;
+ acc_plus = acc_plus * cur_mult + cur_plus;
+ }
+ cur_plus = (cur_mult + 1) * cur_plus;
+ cur_mult *= cur_mult;
+ delta /= 2;
+ }
+ return acc_mult * state + acc_plus;
+}
+
diff --git a/src/haversine/libs/pcg/pcg-global-32.c b/src/haversine/libs/pcg/pcg-global-32.c
new file mode 100644
index 0000000..8c18e48
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-global-32.c
@@ -0,0 +1,56 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+static pcg32_random_t pcg32_global = PCG32_INITIALIZER;
+
+uint32_t pcg32_random()
+{
+ return pcg32_random_r(&pcg32_global);
+}
+
+uint32_t pcg32_boundedrand(uint32_t bound)
+{
+ return pcg32_boundedrand_r(&pcg32_global, bound);
+}
+
+void pcg32_srandom(uint64_t seed, uint64_t seq)
+{
+ pcg32_srandom_r(&pcg32_global, seed, seq);
+}
+
+void pcg32_advance(uint64_t delta)
+{
+ return pcg32_advance_r(&pcg32_global, delta);
+}
+
diff --git a/src/haversine/libs/pcg/pcg-global-64.c b/src/haversine/libs/pcg/pcg-global-64.c
new file mode 100644
index 0000000..26aa677
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-global-64.c
@@ -0,0 +1,59 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+#if PCG_HAS_128BIT_OPS
+
+static pcg64_random_t pcg64_global = PCG64_INITIALIZER;
+
+uint64_t pcg64_random()
+{
+ return pcg64_random_r(&pcg64_global);
+}
+
+uint64_t pcg64_boundedrand(uint64_t bound)
+{
+ return pcg64_boundedrand_r(&pcg64_global, bound);
+}
+
+void pcg64_srandom(pcg128_t seed, pcg128_t seq)
+{
+ pcg64_srandom_r(&pcg64_global, seed, seq);
+}
+
+void pcg64_advance(pcg128_t delta)
+{
+ pcg64_advance_r(&pcg64_global, delta);
+}
+
+#endif
diff --git a/src/haversine/libs/pcg/pcg-output-128.c b/src/haversine/libs/pcg/pcg-output-128.c
new file mode 100644
index 0000000..cb2142e
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-output-128.c
@@ -0,0 +1,64 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/*
+ * Rotate helper functions.
+ */
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t pcg_rotr_128(pcg128_t value, unsigned int rot);
+#endif
+
+/*
+ * Output functions. These are the core of the PCG generation scheme.
+ */
+
+// XSH RS
+
+// XSH RR
+
+// RXS M XS
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t pcg_output_rxs_m_xs_128_128(pcg128_t state);
+#endif
+
+// XSL RR (only defined for >= 64 bits)
+
+// XSL RR RR (only defined for >= 64 bits)
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t pcg_output_xsl_rr_rr_128_128(pcg128_t state);
+#endif
+
diff --git a/src/haversine/libs/pcg/pcg-output-16.c b/src/haversine/libs/pcg/pcg-output-16.c
new file mode 100644
index 0000000..c593f67
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-output-16.c
@@ -0,0 +1,60 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/*
+ * Rotate helper functions.
+ */
+
+extern inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot);
+
+/*
+ * Output functions. These are the core of the PCG generation scheme.
+ */
+
+// XSH RS
+
+extern inline uint16_t pcg_output_xsh_rs_32_16(uint32_t state);
+
+// XSH RR
+
+extern inline uint16_t pcg_output_xsh_rr_32_16(uint32_t state);
+
+// RXS M XS
+
+extern inline uint16_t pcg_output_rxs_m_xs_16_16(uint16_t state);
+
+// XSL RR (only defined for >= 64 bits)
+
+// XSL RR RR (only defined for >= 64 bits)
+
diff --git a/src/haversine/libs/pcg/pcg-output-32.c b/src/haversine/libs/pcg/pcg-output-32.c
new file mode 100644
index 0000000..e291c36
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-output-32.c
@@ -0,0 +1,62 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/*
+ * Rotate helper functions.
+ */
+
+extern inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot);
+
+/*
+ * Output functions. These are the core of the PCG generation scheme.
+ */
+
+// XSH RS
+
+extern inline uint32_t pcg_output_xsh_rs_64_32(uint64_t state);
+
+// XSH RR
+
+extern inline uint32_t pcg_output_xsh_rr_64_32(uint64_t state);
+
+// RXS M XS
+
+extern inline uint32_t pcg_output_rxs_m_xs_32_32(uint32_t state);
+
+// XSL RR (only defined for >= 64 bits)
+
+extern inline uint32_t pcg_output_xsl_rr_64_32(uint64_t state);
+
+// XSL RR RR (only defined for >= 64 bits)
+
diff --git a/src/haversine/libs/pcg/pcg-output-64.c b/src/haversine/libs/pcg/pcg-output-64.c
new file mode 100644
index 0000000..8c6b7e4
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-output-64.c
@@ -0,0 +1,70 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/*
+ * Rotate helper functions.
+ */
+
+extern inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot);
+
+/*
+ * Output functions. These are the core of the PCG generation scheme.
+ */
+
+// XSH RS
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t pcg_output_xsh_rs_128_64(pcg128_t state);
+#endif
+
+// XSH RR
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t pcg_output_xsh_rr_128_64(pcg128_t state);
+#endif
+
+// RXS M XS
+
+extern inline uint64_t pcg_output_rxs_m_xs_64_64(uint64_t state);
+
+// XSL RR (only defined for >= 64 bits)
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state);
+#endif
+
+// XSL RR RR (only defined for >= 64 bits)
+
+extern inline uint64_t pcg_output_xsl_rr_rr_64_64(uint64_t state);
+
diff --git a/src/haversine/libs/pcg/pcg-output-8.c b/src/haversine/libs/pcg/pcg-output-8.c
new file mode 100644
index 0000000..83fe449
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-output-8.c
@@ -0,0 +1,60 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/*
+ * Rotate helper functions.
+ */
+
+extern inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot);
+
+/*
+ * Output functions. These are the core of the PCG generation scheme.
+ */
+
+// XSH RS
+
+extern inline uint8_t pcg_output_xsh_rs_16_8(uint16_t state);
+
+// XSH RR
+
+extern inline uint8_t pcg_output_xsh_rr_16_8(uint16_t state);
+
+// RXS M XS
+
+extern inline uint8_t pcg_output_rxs_m_xs_8_8(uint8_t state);
+
+// XSL RR (only defined for >= 64 bits)
+
+// XSL RR RR (only defined for >= 64 bits)
+
diff --git a/src/haversine/libs/pcg/pcg-rngs-128.c b/src/haversine/libs/pcg/pcg-rngs-128.c
new file mode 100644
index 0000000..8023589
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-rngs-128.c
@@ -0,0 +1,337 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/* Functions to advance the underlying LCG, one version for each size and
+ * each style. These functions are considered semi-private. There is rarely
+ * a good reason to call them directly.
+ */
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_oneseq_128_step_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_oneseq_128_advance_r(struct pcg_state_128* rng,
+ pcg128_t delta);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_mcg_128_step_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_mcg_128_advance_r(struct pcg_state_128* rng,
+ pcg128_t delta);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_unique_128_step_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_unique_128_advance_r(struct pcg_state_128* rng,
+ pcg128_t delta);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_setseq_128_step_r(struct pcg_state_setseq_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_setseq_128_advance_r(struct pcg_state_setseq_128* rng,
+ pcg128_t delta);
+#endif
+
+/* Functions to seed the RNG state, one version for each size and each
+ * style. Unlike the step functions, regular users can and should call
+ * these functions.
+ */
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_oneseq_128_srandom_r(struct pcg_state_128* rng,
+ pcg128_t initstate);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_mcg_128_srandom_r(struct pcg_state_128* rng,
+ pcg128_t initstate);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_unique_128_srandom_r(struct pcg_state_128* rng,
+ pcg128_t initstate);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline void pcg_setseq_128_srandom_r(struct pcg_state_setseq_128* rng,
+ pcg128_t initstate,
+ pcg128_t initseq);
+#endif
+
+/* Now, finally we create each of the individual generators. We provide
+ * a random_r function that provides a random number of the appropriate
+ * type (using the full range of the type) and a boundedrand_r version
+ * that provides
+ *
+ * Implementation notes for boundedrand_r:
+ *
+ * To avoid bias, we need to make the range of the RNG a multiple of
+ * bound, which we do by dropping output less than a threshold.
+ * Let's consider a 32-bit case... A naive scheme to calculate the
+ * threshold would be to do
+ *
+ * uint32_t threshold = 0x100000000ull % bound;
+ *
+ * but 64-bit div/mod is slower than 32-bit div/mod (especially on
+ * 32-bit platforms). In essence, we do
+ *
+ * uint32_t threshold = (0x100000000ull-bound) % bound;
+ *
+ * because this version will calculate the same modulus, but the LHS
+ * value is less than 2^32.
+ *
+ * (Note that using modulo is only wise for good RNGs, poorer RNGs
+ * such as raw LCGs do better using a technique based on division.)
+ * Empricical tests show that division is preferable to modulus for
+ * reducting the range of an RNG. It's faster, and sometimes it can
+ * even be statistically prefereable.
+ */
+
+/* Generation functions for XSH RS */
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_oneseq_128_xsh_rs_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_oneseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_unique_128_xsh_rs_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_unique_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_setseq_128_xsh_rs_64_random_r(struct pcg_state_setseq_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_setseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_setseq_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_mcg_128_xsh_rs_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_mcg_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng, uint64_t bound);
+#endif
+
+/* Generation functions for XSH RR */
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_oneseq_128_xsh_rr_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_oneseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_unique_128_xsh_rr_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_unique_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_setseq_128_xsh_rr_64_random_r(struct pcg_state_setseq_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_setseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_mcg_128_xsh_rr_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_mcg_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng, uint64_t bound);
+#endif
+
+/* Generation functions for RXS M XS (no MCG versions because they
+ * don't make sense when you want to use the entire state)
+ */
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_oneseq_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_oneseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng,
+ pcg128_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_unique_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_unique_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng,
+ pcg128_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_setseq_128_rxs_m_xs_128_random_r(struct pcg_state_setseq_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_setseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_setseq_128* rng,
+ pcg128_t bound);
+#endif
+
+/* Generation functions for XSL RR (only defined for "large" types) */
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_oneseq_128_xsl_rr_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_oneseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_unique_128_xsl_rr_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_unique_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_setseq_128_xsl_rr_64_random_r(struct pcg_state_setseq_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_setseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng,
+ uint64_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_mcg_128_xsl_rr_64_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline uint64_t
+pcg_mcg_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng, uint64_t bound);
+#endif
+
+/* Generation functions for XSL RR RR (only defined for "large" types) */
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_oneseq_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_oneseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng,
+ pcg128_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_unique_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_unique_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng,
+ pcg128_t bound);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_setseq_128_xsl_rr_rr_128_random_r(struct pcg_state_setseq_128* rng);
+#endif
+
+#if PCG_HAS_128BIT_OPS
+extern inline pcg128_t
+pcg_setseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_setseq_128* rng,
+ pcg128_t bound);
+#endif
+
diff --git a/src/haversine/libs/pcg/pcg-rngs-16.c b/src/haversine/libs/pcg/pcg-rngs-16.c
new file mode 100644
index 0000000..6d4e9b6
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-rngs-16.c
@@ -0,0 +1,183 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/* Functions to advance the underlying LCG, one version for each size and
+ * each style. These functions are considered semi-private. There is rarely
+ * a good reason to call them directly.
+ */
+
+extern inline void pcg_oneseq_16_step_r(struct pcg_state_16* rng);
+
+extern inline void pcg_oneseq_16_advance_r(struct pcg_state_16* rng,
+ uint16_t delta);
+
+extern inline void pcg_mcg_16_step_r(struct pcg_state_16* rng);
+
+extern inline void pcg_mcg_16_advance_r(struct pcg_state_16* rng,
+ uint16_t delta);
+
+extern inline void pcg_unique_16_step_r(struct pcg_state_16* rng);
+
+extern inline void pcg_unique_16_advance_r(struct pcg_state_16* rng,
+ uint16_t delta);
+
+extern inline void pcg_setseq_16_step_r(struct pcg_state_setseq_16* rng);
+
+extern inline void pcg_setseq_16_advance_r(struct pcg_state_setseq_16* rng,
+ uint16_t delta);
+
+/* Functions to seed the RNG state, one version for each size and each
+ * style. Unlike the step functions, regular users can and should call
+ * these functions.
+ */
+
+extern inline void pcg_oneseq_16_srandom_r(struct pcg_state_16* rng,
+ uint16_t initstate);
+
+extern inline void pcg_mcg_16_srandom_r(struct pcg_state_16* rng,
+ uint16_t initstate);
+
+extern inline void pcg_unique_16_srandom_r(struct pcg_state_16* rng,
+ uint16_t initstate);
+
+extern inline void pcg_setseq_16_srandom_r(struct pcg_state_setseq_16* rng,
+ uint16_t initstate,
+ uint16_t initseq);
+
+/* Now, finally we create each of the individual generators. We provide
+ * a random_r function that provides a random number of the appropriate
+ * type (using the full range of the type) and a boundedrand_r version
+ * that provides
+ *
+ * Implementation notes for boundedrand_r:
+ *
+ * To avoid bias, we need to make the range of the RNG a multiple of
+ * bound, which we do by dropping output less than a threshold.
+ * Let's consider a 32-bit case... A naive scheme to calculate the
+ * threshold would be to do
+ *
+ * uint32_t threshold = 0x100000000ull % bound;
+ *
+ * but 64-bit div/mod is slower than 32-bit div/mod (especially on
+ * 32-bit platforms). In essence, we do
+ *
+ * uint32_t threshold = (0x100000000ull-bound) % bound;
+ *
+ * because this version will calculate the same modulus, but the LHS
+ * value is less than 2^32.
+ *
+ * (Note that using modulo is only wise for good RNGs, poorer RNGs
+ * such as raw LCGs do better using a technique based on division.)
+ * Empricical tests show that division is preferable to modulus for
+ * reducting the range of an RNG. It's faster, and sometimes it can
+ * even be statistically prefereable.
+ */
+
+/* Generation functions for XSH RS */
+
+extern inline uint8_t pcg_oneseq_16_xsh_rs_8_random_r(struct pcg_state_16* rng);
+
+extern inline uint8_t
+pcg_oneseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound);
+
+extern inline uint8_t pcg_unique_16_xsh_rs_8_random_r(struct pcg_state_16* rng);
+
+extern inline uint8_t
+pcg_unique_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound);
+
+extern inline uint8_t
+pcg_setseq_16_xsh_rs_8_random_r(struct pcg_state_setseq_16* rng);
+
+extern inline uint8_t
+pcg_setseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_setseq_16* rng,
+ uint8_t bound);
+
+extern inline uint8_t pcg_mcg_16_xsh_rs_8_random_r(struct pcg_state_16* rng);
+
+extern inline uint8_t
+pcg_mcg_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound);
+
+/* Generation functions for XSH RR */
+
+extern inline uint8_t pcg_oneseq_16_xsh_rr_8_random_r(struct pcg_state_16* rng);
+
+extern inline uint8_t
+pcg_oneseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound);
+
+extern inline uint8_t pcg_unique_16_xsh_rr_8_random_r(struct pcg_state_16* rng);
+
+extern inline uint8_t
+pcg_unique_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound);
+
+extern inline uint8_t
+pcg_setseq_16_xsh_rr_8_random_r(struct pcg_state_setseq_16* rng);
+
+extern inline uint8_t
+pcg_setseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_setseq_16* rng,
+ uint8_t bound);
+
+extern inline uint8_t pcg_mcg_16_xsh_rr_8_random_r(struct pcg_state_16* rng);
+
+extern inline uint8_t
+pcg_mcg_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng, uint8_t bound);
+
+/* Generation functions for RXS M XS (no MCG versions because they
+ * don't make sense when you want to use the entire state)
+ */
+
+extern inline uint16_t
+pcg_oneseq_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng);
+
+extern inline uint16_t
+pcg_oneseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng,
+ uint16_t bound);
+
+extern inline uint16_t
+pcg_unique_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng);
+
+extern inline uint16_t
+pcg_unique_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng,
+ uint16_t bound);
+
+extern inline uint16_t
+pcg_setseq_16_rxs_m_xs_16_random_r(struct pcg_state_setseq_16* rng);
+
+extern inline uint16_t
+pcg_setseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_setseq_16* rng,
+ uint16_t bound);
+
+/* Generation functions for XSL RR (only defined for "large" types) */
+
+/* Generation functions for XSL RR RR (only defined for "large" types) */
+
diff --git a/src/haversine/libs/pcg/pcg-rngs-32.c b/src/haversine/libs/pcg/pcg-rngs-32.c
new file mode 100644
index 0000000..1c8da7e
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-rngs-32.c
@@ -0,0 +1,187 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/* Functions to advance the underlying LCG, one version for each size and
+ * each style. These functions are considered semi-private. There is rarely
+ * a good reason to call them directly.
+ */
+
+extern inline void pcg_oneseq_32_step_r(struct pcg_state_32* rng);
+
+extern inline void pcg_oneseq_32_advance_r(struct pcg_state_32* rng,
+ uint32_t delta);
+
+extern inline void pcg_mcg_32_step_r(struct pcg_state_32* rng);
+
+extern inline void pcg_mcg_32_advance_r(struct pcg_state_32* rng,
+ uint32_t delta);
+
+extern inline void pcg_unique_32_step_r(struct pcg_state_32* rng);
+
+extern inline void pcg_unique_32_advance_r(struct pcg_state_32* rng,
+ uint32_t delta);
+
+extern inline void pcg_setseq_32_step_r(struct pcg_state_setseq_32* rng);
+
+extern inline void pcg_setseq_32_advance_r(struct pcg_state_setseq_32* rng,
+ uint32_t delta);
+
+/* Functions to seed the RNG state, one version for each size and each
+ * style. Unlike the step functions, regular users can and should call
+ * these functions.
+ */
+
+extern inline void pcg_oneseq_32_srandom_r(struct pcg_state_32* rng,
+ uint32_t initstate);
+
+extern inline void pcg_mcg_32_srandom_r(struct pcg_state_32* rng,
+ uint32_t initstate);
+
+extern inline void pcg_unique_32_srandom_r(struct pcg_state_32* rng,
+ uint32_t initstate);
+
+extern inline void pcg_setseq_32_srandom_r(struct pcg_state_setseq_32* rng,
+ uint32_t initstate,
+ uint32_t initseq);
+
+/* Now, finally we create each of the individual generators. We provide
+ * a random_r function that provides a random number of the appropriate
+ * type (using the full range of the type) and a boundedrand_r version
+ * that provides
+ *
+ * Implementation notes for boundedrand_r:
+ *
+ * To avoid bias, we need to make the range of the RNG a multiple of
+ * bound, which we do by dropping output less than a threshold.
+ * Let's consider a 32-bit case... A naive scheme to calculate the
+ * threshold would be to do
+ *
+ * uint32_t threshold = 0x100000000ull % bound;
+ *
+ * but 64-bit div/mod is slower than 32-bit div/mod (especially on
+ * 32-bit platforms). In essence, we do
+ *
+ * uint32_t threshold = (0x100000000ull-bound) % bound;
+ *
+ * because this version will calculate the same modulus, but the LHS
+ * value is less than 2^32.
+ *
+ * (Note that using modulo is only wise for good RNGs, poorer RNGs
+ * such as raw LCGs do better using a technique based on division.)
+ * Empricical tests show that division is preferable to modulus for
+ * reducting the range of an RNG. It's faster, and sometimes it can
+ * even be statistically prefereable.
+ */
+
+/* Generation functions for XSH RS */
+
+extern inline uint16_t
+pcg_oneseq_32_xsh_rs_16_random_r(struct pcg_state_32* rng);
+
+extern inline uint16_t
+pcg_oneseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound);
+
+extern inline uint16_t
+pcg_unique_32_xsh_rs_16_random_r(struct pcg_state_32* rng);
+
+extern inline uint16_t
+pcg_unique_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound);
+
+extern inline uint16_t
+pcg_setseq_32_xsh_rs_16_random_r(struct pcg_state_setseq_32* rng);
+
+extern inline uint16_t
+pcg_setseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_setseq_32* rng,
+ uint16_t bound);
+
+extern inline uint16_t pcg_mcg_32_xsh_rs_16_random_r(struct pcg_state_32* rng);
+
+extern inline uint16_t
+pcg_mcg_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound);
+
+/* Generation functions for XSH RR */
+
+extern inline uint16_t
+pcg_oneseq_32_xsh_rr_16_random_r(struct pcg_state_32* rng);
+
+extern inline uint16_t
+pcg_oneseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound);
+
+extern inline uint16_t
+pcg_unique_32_xsh_rr_16_random_r(struct pcg_state_32* rng);
+
+extern inline uint16_t
+pcg_unique_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound);
+
+extern inline uint16_t
+pcg_setseq_32_xsh_rr_16_random_r(struct pcg_state_setseq_32* rng);
+
+extern inline uint16_t
+pcg_setseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_setseq_32* rng,
+ uint16_t bound);
+
+extern inline uint16_t pcg_mcg_32_xsh_rr_16_random_r(struct pcg_state_32* rng);
+
+extern inline uint16_t
+pcg_mcg_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng, uint16_t bound);
+
+/* Generation functions for RXS M XS (no MCG versions because they
+ * don't make sense when you want to use the entire state)
+ */
+
+extern inline uint32_t
+pcg_oneseq_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng);
+
+extern inline uint32_t
+pcg_oneseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng,
+ uint32_t bound);
+
+extern inline uint32_t
+pcg_unique_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng);
+
+extern inline uint32_t
+pcg_unique_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng,
+ uint32_t bound);
+
+extern inline uint32_t
+pcg_setseq_32_rxs_m_xs_32_random_r(struct pcg_state_setseq_32* rng);
+
+extern inline uint32_t
+pcg_setseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_setseq_32* rng,
+ uint32_t bound);
+
+/* Generation functions for XSL RR (only defined for "large" types) */
+
+/* Generation functions for XSL RR RR (only defined for "large" types) */
+
diff --git a/src/haversine/libs/pcg/pcg-rngs-64.c b/src/haversine/libs/pcg/pcg-rngs-64.c
new file mode 100644
index 0000000..cc0ff2c
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-rngs-64.c
@@ -0,0 +1,232 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/* Functions to advance the underlying LCG, one version for each size and
+ * each style. These functions are considered semi-private. There is rarely
+ * a good reason to call them directly.
+ */
+
+extern inline void pcg_oneseq_64_step_r(struct pcg_state_64* rng);
+
+extern inline void pcg_oneseq_64_advance_r(struct pcg_state_64* rng,
+ uint64_t delta);
+
+extern inline void pcg_mcg_64_step_r(struct pcg_state_64* rng);
+
+extern inline void pcg_mcg_64_advance_r(struct pcg_state_64* rng,
+ uint64_t delta);
+
+extern inline void pcg_unique_64_step_r(struct pcg_state_64* rng);
+
+extern inline void pcg_unique_64_advance_r(struct pcg_state_64* rng,
+ uint64_t delta);
+
+extern inline void pcg_setseq_64_step_r(struct pcg_state_setseq_64* rng);
+
+extern inline void pcg_setseq_64_advance_r(struct pcg_state_setseq_64* rng,
+ uint64_t delta);
+
+/* Functions to seed the RNG state, one version for each size and each
+ * style. Unlike the step functions, regular users can and should call
+ * these functions.
+ */
+
+extern inline void pcg_oneseq_64_srandom_r(struct pcg_state_64* rng,
+ uint64_t initstate);
+
+extern inline void pcg_mcg_64_srandom_r(struct pcg_state_64* rng,
+ uint64_t initstate);
+
+extern inline void pcg_unique_64_srandom_r(struct pcg_state_64* rng,
+ uint64_t initstate);
+
+extern inline void pcg_setseq_64_srandom_r(struct pcg_state_setseq_64* rng,
+ uint64_t initstate,
+ uint64_t initseq);
+
+/* Now, finally we create each of the individual generators. We provide
+ * a random_r function that provides a random number of the appropriate
+ * type (using the full range of the type) and a boundedrand_r version
+ * that provides
+ *
+ * Implementation notes for boundedrand_r:
+ *
+ * To avoid bias, we need to make the range of the RNG a multiple of
+ * bound, which we do by dropping output less than a threshold.
+ * Let's consider a 32-bit case... A naive scheme to calculate the
+ * threshold would be to do
+ *
+ * uint32_t threshold = 0x100000000ull % bound;
+ *
+ * but 64-bit div/mod is slower than 32-bit div/mod (especially on
+ * 32-bit platforms). In essence, we do
+ *
+ * uint32_t threshold = (0x100000000ull-bound) % bound;
+ *
+ * because this version will calculate the same modulus, but the LHS
+ * value is less than 2^32.
+ *
+ * (Note that using modulo is only wise for good RNGs, poorer RNGs
+ * such as raw LCGs do better using a technique based on division.)
+ * Empricical tests show that division is preferable to modulus for
+ * reducting the range of an RNG. It's faster, and sometimes it can
+ * even be statistically prefereable.
+ */
+
+/* Generation functions for XSH RS */
+
+extern inline uint32_t
+pcg_oneseq_64_xsh_rs_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_oneseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+extern inline uint32_t
+pcg_unique_64_xsh_rs_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_unique_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+extern inline uint32_t
+pcg_setseq_64_xsh_rs_32_random_r(struct pcg_state_setseq_64* rng);
+
+extern inline uint32_t
+pcg_setseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint32_t bound);
+
+extern inline uint32_t pcg_mcg_64_xsh_rs_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_mcg_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+/* Generation functions for XSH RR */
+
+extern inline uint32_t
+pcg_oneseq_64_xsh_rr_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_oneseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+extern inline uint32_t
+pcg_unique_64_xsh_rr_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_unique_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+extern inline uint32_t
+pcg_setseq_64_xsh_rr_32_random_r(struct pcg_state_setseq_64* rng);
+
+extern inline uint32_t
+pcg_setseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint32_t bound);
+
+extern inline uint32_t pcg_mcg_64_xsh_rr_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_mcg_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+/* Generation functions for RXS M XS (no MCG versions because they
+ * don't make sense when you want to use the entire state)
+ */
+
+extern inline uint64_t
+pcg_oneseq_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng);
+
+extern inline uint64_t
+pcg_oneseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng,
+ uint64_t bound);
+
+extern inline uint64_t
+pcg_unique_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng);
+
+extern inline uint64_t
+pcg_unique_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng,
+ uint64_t bound);
+
+extern inline uint64_t
+pcg_setseq_64_rxs_m_xs_64_random_r(struct pcg_state_setseq_64* rng);
+
+extern inline uint64_t
+pcg_setseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint64_t bound);
+
+/* Generation functions for XSL RR (only defined for "large" types) */
+
+extern inline uint32_t
+pcg_oneseq_64_xsl_rr_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_oneseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+extern inline uint32_t
+pcg_unique_64_xsl_rr_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_unique_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+extern inline uint32_t
+pcg_setseq_64_xsl_rr_32_random_r(struct pcg_state_setseq_64* rng);
+
+extern inline uint32_t
+pcg_setseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint32_t bound);
+
+extern inline uint32_t pcg_mcg_64_xsl_rr_32_random_r(struct pcg_state_64* rng);
+
+extern inline uint32_t
+pcg_mcg_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng, uint32_t bound);
+
+/* Generation functions for XSL RR RR (only defined for "large" types) */
+
+extern inline uint64_t
+pcg_oneseq_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng);
+
+extern inline uint64_t
+pcg_oneseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng,
+ uint64_t bound);
+
+extern inline uint64_t
+pcg_unique_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng);
+
+extern inline uint64_t
+pcg_unique_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng,
+ uint64_t bound);
+
+extern inline uint64_t
+pcg_setseq_64_xsl_rr_rr_64_random_r(struct pcg_state_setseq_64* rng);
+
+extern inline uint64_t
+pcg_setseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint64_t bound);
+
diff --git a/src/haversine/libs/pcg/pcg-rngs-8.c b/src/haversine/libs/pcg/pcg-rngs-8.c
new file mode 100644
index 0000000..8779aac
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg-rngs-8.c
@@ -0,0 +1,128 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * The contents of this file were mechanically derived from pcg_variants.h
+ * (every inline function defined there gets an exern declaration here).
+ */
+
+#include "pcg_variants.h"
+
+/* Functions to advance the underlying LCG, one version for each size and
+ * each style. These functions are considered semi-private. There is rarely
+ * a good reason to call them directly.
+ */
+
+extern inline void pcg_oneseq_8_step_r(struct pcg_state_8* rng);
+
+extern inline void pcg_oneseq_8_advance_r(struct pcg_state_8* rng,
+ uint8_t delta);
+
+extern inline void pcg_mcg_8_step_r(struct pcg_state_8* rng);
+
+extern inline void pcg_mcg_8_advance_r(struct pcg_state_8* rng, uint8_t delta);
+
+extern inline void pcg_unique_8_step_r(struct pcg_state_8* rng);
+
+extern inline void pcg_unique_8_advance_r(struct pcg_state_8* rng,
+ uint8_t delta);
+
+extern inline void pcg_setseq_8_step_r(struct pcg_state_setseq_8* rng);
+
+extern inline void pcg_setseq_8_advance_r(struct pcg_state_setseq_8* rng,
+ uint8_t delta);
+
+/* Functions to seed the RNG state, one version for each size and each
+ * style. Unlike the step functions, regular users can and should call
+ * these functions.
+ */
+
+extern inline void pcg_oneseq_8_srandom_r(struct pcg_state_8* rng,
+ uint8_t initstate);
+
+extern inline void pcg_mcg_8_srandom_r(struct pcg_state_8* rng,
+ uint8_t initstate);
+
+extern inline void pcg_unique_8_srandom_r(struct pcg_state_8* rng,
+ uint8_t initstate);
+
+extern inline void pcg_setseq_8_srandom_r(struct pcg_state_setseq_8* rng,
+ uint8_t initstate, uint8_t initseq);
+
+/* Now, finally we create each of the individual generators. We provide
+ * a random_r function that provides a random number of the appropriate
+ * type (using the full range of the type) and a boundedrand_r version
+ * that provides
+ *
+ * Implementation notes for boundedrand_r:
+ *
+ * To avoid bias, we need to make the range of the RNG a multiple of
+ * bound, which we do by dropping output less than a threshold.
+ * Let's consider a 32-bit case... A naive scheme to calculate the
+ * threshold would be to do
+ *
+ * uint32_t threshold = 0x100000000ull % bound;
+ *
+ * but 64-bit div/mod is slower than 32-bit div/mod (especially on
+ * 32-bit platforms). In essence, we do
+ *
+ * uint32_t threshold = (0x100000000ull-bound) % bound;
+ *
+ * because this version will calculate the same modulus, but the LHS
+ * value is less than 2^32.
+ *
+ * (Note that using modulo is only wise for good RNGs, poorer RNGs
+ * such as raw LCGs do better using a technique based on division.)
+ * Empricical tests show that division is preferable to modulus for
+ * reducting the range of an RNG. It's faster, and sometimes it can
+ * even be statistically prefereable.
+ */
+
+/* Generation functions for XSH RS */
+
+/* Generation functions for XSH RR */
+
+/* Generation functions for RXS M XS (no MCG versions because they
+ * don't make sense when you want to use the entire state)
+ */
+
+extern inline uint8_t pcg_oneseq_8_rxs_m_xs_8_random_r(struct pcg_state_8* rng);
+
+extern inline uint8_t
+pcg_oneseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_8* rng, uint8_t bound);
+
+extern inline uint8_t
+pcg_setseq_8_rxs_m_xs_8_random_r(struct pcg_state_setseq_8* rng);
+
+extern inline uint8_t
+pcg_setseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_setseq_8* rng,
+ uint8_t bound);
+
+/* Generation functions for XSL RR (only defined for "large" types) */
+
+/* Generation functions for XSL RR RR (only defined for "large" types) */
+
diff --git a/src/haversine/libs/pcg/pcg.c b/src/haversine/libs/pcg/pcg.c
new file mode 100644
index 0000000..cf29e6d
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg.c
@@ -0,0 +1,16 @@
+#include "pcg_variants.h"
+#include "pcg-advance-128.c"
+#include "pcg-advance-16.c"
+#include "pcg-advance-32.c"
+#include "pcg-advance-64.c"
+#include "pcg-advance-8.c"
+#include "pcg-output-128.c"
+#include "pcg-output-16.c"
+#include "pcg-output-32.c"
+#include "pcg-output-64.c"
+#include "pcg-output-8.c"
+#include "pcg-rngs-128.c"
+#include "pcg-rngs-16.c"
+#include "pcg-rngs-32.c"
+#include "pcg-rngs-64.c"
+#include "pcg-rngs-8.c"
diff --git a/src/haversine/libs/pcg/pcg_variants.h b/src/haversine/libs/pcg/pcg_variants.h
new file mode 100644
index 0000000..83edae8
--- /dev/null
+++ b/src/haversine/libs/pcg/pcg_variants.h
@@ -0,0 +1,2213 @@
+/*
+ * PCG Random Number Generation for C.
+ *
+ * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * For additional information about the PCG random number generation scheme,
+ * including its license and other licensing options, visit
+ *
+ * http://www.pcg-random.org
+ */
+
+/*
+ * This code is derived from the canonical C++ PCG implementation, which
+ * has many additional features and is preferable if you can use C++ in
+ * your project.
+ *
+ * Much of the derivation was performed mechanically. In particular, the
+ * output functions were generated by compiling the C++ output functions
+ * into LLVM bitcode and then transforming that using the LLVM C backend
+ * (from https://github.com/draperlaboratory/llvm-cbe), and then
+ * postprocessing and hand editing the output.
+ *
+ * Much of the remaining code was generated by C-preprocessor metaprogramming.
+ */
+
+#ifndef PCG_VARIANTS_H_INCLUDED
+#define PCG_VARIANTS_H_INCLUDED 1
+
+#include <inttypes.h>
+
+#if __SIZEOF_INT128__
+typedef __uint128_t pcg128_t;
+#define PCG_128BIT_CONSTANT(high,low) \
+((((pcg128_t)high) << 64) + low)
+#define PCG_HAS_128BIT_OPS 1
+#else
+#error "non"
+#endif
+
+#if __GNUC_GNU_INLINE__ && !defined(__cplusplus)
+#error Nonstandard GNU inlining semanatics. Compile with -std=c99 or better.
+// We could instead use macros PCG_INLINE and PCG_EXTERN_INLINE
+// but better to just reject ancient C code.
+#endif
+
+#if __cplusplus
+extern "C" {
+#endif
+
+ /*
+ * Rotate helper functions.
+ */
+
+ inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot)
+ {
+ /* Unfortunately, clang is kinda pathetic when it comes to properly
+ * recognizing idiomatic rotate code, so for clang we actually provide
+ * assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss.
+ */
+#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__)
+ asm ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
+ return value;
+#else
+ return (value >> rot) | (value << ((- rot) & 7));
+#endif
+ }
+
+ inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot)
+ {
+#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__)
+ asm ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
+ return value;
+#else
+ return (value >> rot) | (value << ((- rot) & 15));
+#endif
+ }
+
+ inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot)
+ {
+#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__)
+ asm ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
+ return value;
+#else
+ return (value >> rot) | (value << ((- rot) & 31));
+#endif
+ }
+
+ inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot)
+ {
+#if 0 && PCG_USE_INLINE_ASM && __clang__ && __x86_64__
+ // For whatever reason, clang actually *does* generator rotq by
+ // itself, so we don't need this code.
+ asm ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
+ return value;
+#else
+ return (value >> rot) | (value << ((- rot) & 63));
+#endif
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t pcg_rotr_128(pcg128_t value, unsigned int rot)
+ {
+ return (value >> rot) | (value << ((- rot) & 127));
+ }
+#endif
+
+ /*
+ * Output functions. These are the core of the PCG generation scheme.
+ */
+
+ // XSH RS
+
+ inline uint8_t pcg_output_xsh_rs_16_8(uint16_t state)
+ {
+ return (uint8_t)(((state >> 7u) ^ state) >> ((state >> 14u) + 3u));
+ }
+
+ inline uint16_t pcg_output_xsh_rs_32_16(uint32_t state)
+ {
+ return (uint16_t)(((state >> 11u) ^ state) >> ((state >> 30u) + 11u));
+ }
+
+ inline uint32_t pcg_output_xsh_rs_64_32(uint64_t state)
+ {
+
+ return (uint32_t)(((state >> 22u) ^ state) >> ((state >> 61u) + 22u));
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_output_xsh_rs_128_64(pcg128_t state)
+ {
+ return (uint64_t)(((state >> 43u) ^ state) >> ((state >> 124u) + 45u));
+ }
+#endif
+
+ // XSH RR
+
+ inline uint8_t pcg_output_xsh_rr_16_8(uint16_t state)
+ {
+ return pcg_rotr_8(((state >> 5u) ^ state) >> 5u, state >> 13u);
+ }
+
+ inline uint16_t pcg_output_xsh_rr_32_16(uint32_t state)
+ {
+ return pcg_rotr_16(((state >> 10u) ^ state) >> 12u, state >> 28u);
+ }
+
+ inline uint32_t pcg_output_xsh_rr_64_32(uint64_t state)
+ {
+ return pcg_rotr_32(((state >> 18u) ^ state) >> 27u, state >> 59u);
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_output_xsh_rr_128_64(pcg128_t state)
+ {
+ return pcg_rotr_64(((state >> 29u) ^ state) >> 58u, state >> 122u);
+ }
+#endif
+
+ // RXS M XS
+
+ inline uint8_t pcg_output_rxs_m_xs_8_8(uint8_t state)
+ {
+ uint8_t word = ((state >> ((state >> 6u) + 2u)) ^ state) * 217u;
+ return (word >> 6u) ^ word;
+ }
+
+ inline uint16_t pcg_output_rxs_m_xs_16_16(uint16_t state)
+ {
+ uint16_t word = ((state >> ((state >> 13u) + 3u)) ^ state) * 62169u;
+ return (word >> 11u) ^ word;
+ }
+
+ inline uint32_t pcg_output_rxs_m_xs_32_32(uint32_t state)
+ {
+ uint32_t word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
+ return (word >> 22u) ^ word;
+ }
+
+ inline uint64_t pcg_output_rxs_m_xs_64_64(uint64_t state)
+ {
+ uint64_t word = ((state >> ((state >> 59u) + 5u)) ^ state)
+ * 12605985483714917081ull;
+ return (word >> 43u) ^ word;
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t pcg_output_rxs_m_xs_128_128(pcg128_t state)
+ {
+ pcg128_t word = ((state >> ((state >> 122u) + 6u)) ^ state)
+ * (PCG_128BIT_CONSTANT(17766728186571221404ULL,
+ 12605985483714917081ULL));
+ // 327738287884841127335028083622016905945
+ return (word >> 86u) ^ word;
+ }
+#endif
+
+ // XSL RR (only defined for >= 64 bits)
+
+ inline uint32_t pcg_output_xsl_rr_64_32(uint64_t state)
+ {
+ return pcg_rotr_32(((uint32_t)(state >> 32u)) ^ (uint32_t)state,
+ state >> 59u);
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state)
+ {
+ return pcg_rotr_64(((uint64_t)(state >> 64u)) ^ (uint64_t)state,
+ state >> 122u);
+ }
+#endif
+
+ // XSL RR RR (only defined for >= 64 bits)
+
+ inline uint64_t pcg_output_xsl_rr_rr_64_64(uint64_t state)
+ {
+ uint32_t rot1 = (uint32_t)(state >> 59u);
+ uint32_t high = (uint32_t)(state >> 32u);
+ uint32_t low = (uint32_t)state;
+ uint32_t xored = high ^ low;
+ uint32_t newlow = pcg_rotr_32(xored, rot1);
+ uint32_t newhigh = pcg_rotr_32(high, newlow & 31u);
+ return (((uint64_t)newhigh) << 32u) | newlow;
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t pcg_output_xsl_rr_rr_128_128(pcg128_t state)
+ {
+ uint32_t rot1 = (uint32_t)(state >> 122u);
+ uint64_t high = (uint64_t)(state >> 64u);
+ uint64_t low = (uint64_t)state;
+ uint64_t xored = high ^ low;
+ uint64_t newlow = pcg_rotr_64(xored, rot1);
+ uint64_t newhigh = pcg_rotr_64(high, newlow & 63u);
+ return (((pcg128_t)newhigh) << 64u) | newlow;
+ }
+#endif
+
+#define PCG_DEFAULT_MULTIPLIER_8 141U
+#define PCG_DEFAULT_MULTIPLIER_16 12829U
+#define PCG_DEFAULT_MULTIPLIER_32 747796405U
+#define PCG_DEFAULT_MULTIPLIER_64 6364136223846793005ULL
+
+#define PCG_DEFAULT_INCREMENT_8 77U
+#define PCG_DEFAULT_INCREMENT_16 47989U
+#define PCG_DEFAULT_INCREMENT_32 2891336453U
+#define PCG_DEFAULT_INCREMENT_64 1442695040888963407ULL
+
+#if PCG_HAS_128BIT_OPS
+#define PCG_DEFAULT_MULTIPLIER_128 \
+PCG_128BIT_CONSTANT(2549297995355413924ULL,4865540595714422341ULL)
+#define PCG_DEFAULT_INCREMENT_128 \
+PCG_128BIT_CONSTANT(6364136223846793005ULL,1442695040888963407ULL)
+#endif
+
+ /*
+ * Static initialization constants (if you can't call srandom for some
+ * bizarre reason).
+ */
+
+#if PCG_HAS_128BIT_OPS
+#define PCG_STATE_ONESEQ_8_INITIALIZER { 0xd7U }
+#define PCG_STATE_ONESEQ_16_INITIALIZER { 0x20dfU }
+#define PCG_STATE_ONESEQ_32_INITIALIZER { 0x46b56677U }
+#define PCG_STATE_ONESEQ_64_INITIALIZER { 0x4d595df4d0f33173ULL }
+#define PCG_STATE_ONESEQ_128_INITIALIZER \
+{ PCG_128BIT_CONSTANT(0xb8dc10e158a92392ULL, 0x98046df007ec0a53ULL) }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+#define PCG_STATE_UNIQUE_8_INITIALIZER PCG_STATE_ONESEQ_8_INITIALIZER
+#define PCG_STATE_UNIQUE_16_INITIALIZER PCG_STATE_ONESEQ_16_INITIALIZER
+#define PCG_STATE_UNIQUE_32_INITIALIZER PCG_STATE_ONESEQ_32_INITIALIZER
+#define PCG_STATE_UNIQUE_64_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER
+#define PCG_STATE_UNIQUE_128_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER
+#endif
+
+#if PCG_HAS_128BIT_OPS
+#define PCG_STATE_MCG_8_INITIALIZER { 0xe5U }
+#define PCG_STATE_MCG_16_INITIALIZER { 0xa5e5U }
+#define PCG_STATE_MCG_32_INITIALIZER { 0xd15ea5e5U }
+#define PCG_STATE_MCG_64_INITIALIZER { 0xcafef00dd15ea5e5ULL }
+#define PCG_STATE_MCG_128_INITIALIZER \
+{ PCG_128BIT_CONSTANT(0x0000000000000000ULL, 0xcafef00dd15ea5e5ULL) }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+#define PCG_STATE_SETSEQ_8_INITIALIZER { 0x9bU, 0xdbU }
+#define PCG_STATE_SETSEQ_16_INITIALIZER { 0xe39bU, 0x5bdbU }
+#define PCG_STATE_SETSEQ_32_INITIALIZER { 0xec02d89bU, 0x94b95bdbU }
+#define PCG_STATE_SETSEQ_64_INITIALIZER \
+{ 0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL }
+#define PCG_STATE_SETSEQ_128_INITIALIZER \
+{ PCG_128BIT_CONSTANT(0x979c9a98d8462005ULL, 0x7d3e9cb6cfe0549bULL), \
+PCG_128BIT_CONSTANT(0x0000000000000001ULL, 0xda3e39cb94b95bdbULL) }
+#endif
+
+ /* Representations for the oneseq, mcg, and unique variants */
+
+ struct pcg_state_8 {
+ uint8_t state;
+ };
+
+ struct pcg_state_16 {
+ uint16_t state;
+ };
+
+ struct pcg_state_32 {
+ uint32_t state;
+ };
+
+ struct pcg_state_64 {
+ uint64_t state;
+ };
+
+#if PCG_HAS_128BIT_OPS
+ struct pcg_state_128 {
+ pcg128_t state;
+ };
+#endif
+
+ /* Representations setseq variants */
+
+ struct pcg_state_setseq_8 {
+ uint8_t state;
+ uint8_t inc;
+ };
+
+ struct pcg_state_setseq_16 {
+ uint16_t state;
+ uint16_t inc;
+ };
+
+ struct pcg_state_setseq_32 {
+ uint32_t state;
+ uint32_t inc;
+ };
+
+ struct pcg_state_setseq_64 {
+ uint64_t state;
+ uint64_t inc;
+ };
+
+#if PCG_HAS_128BIT_OPS
+ struct pcg_state_setseq_128 {
+ pcg128_t state;
+ pcg128_t inc;
+ };
+#endif
+
+ /* Multi-step advance functions (jump-ahead, jump-back) */
+
+ extern uint8_t pcg_advance_lcg_8(uint8_t state, uint8_t delta, uint8_t cur_mult,
+ uint8_t cur_plus);
+ extern uint16_t pcg_advance_lcg_16(uint16_t state, uint16_t delta,
+ uint16_t cur_mult, uint16_t cur_plus);
+ extern uint32_t pcg_advance_lcg_32(uint32_t state, uint32_t delta,
+ uint32_t cur_mult, uint32_t cur_plus);
+ extern uint64_t pcg_advance_lcg_64(uint64_t state, uint64_t delta,
+ uint64_t cur_mult, uint64_t cur_plus);
+
+#if PCG_HAS_128BIT_OPS
+ extern pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta,
+ pcg128_t cur_mult, pcg128_t cur_plus);
+#endif
+
+ /* Functions to advance the underlying LCG, one version for each size and
+ * each style. These functions are considered semi-private. There is rarely
+ * a good reason to call them directly.
+ */
+
+ inline void pcg_oneseq_8_step_r(struct pcg_state_8* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8
+ + PCG_DEFAULT_INCREMENT_8;
+ }
+
+ inline void pcg_oneseq_8_advance_r(struct pcg_state_8* rng, uint8_t delta)
+ {
+ rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8,
+ PCG_DEFAULT_INCREMENT_8);
+ }
+
+ inline void pcg_mcg_8_step_r(struct pcg_state_8* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8;
+ }
+
+ inline void pcg_mcg_8_advance_r(struct pcg_state_8* rng, uint8_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, 0u);
+ }
+
+ inline void pcg_unique_8_step_r(struct pcg_state_8* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8
+ + (uint8_t)(((intptr_t)rng) | 1u);
+ }
+
+ inline void pcg_unique_8_advance_r(struct pcg_state_8* rng, uint8_t delta)
+ {
+ rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8,
+ (uint8_t)(((intptr_t)rng) | 1u));
+ }
+
+ inline void pcg_setseq_8_step_r(struct pcg_state_setseq_8* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8 + rng->inc;
+ }
+
+ inline void pcg_setseq_8_advance_r(struct pcg_state_setseq_8* rng,
+ uint8_t delta)
+ {
+ rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8,
+ rng->inc);
+ }
+
+ inline void pcg_oneseq_16_step_r(struct pcg_state_16* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16
+ + PCG_DEFAULT_INCREMENT_16;
+ }
+
+ inline void pcg_oneseq_16_advance_r(struct pcg_state_16* rng, uint16_t delta)
+ {
+ rng->state = pcg_advance_lcg_16(
+ rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, PCG_DEFAULT_INCREMENT_16);
+ }
+
+ inline void pcg_mcg_16_step_r(struct pcg_state_16* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16;
+ }
+
+ inline void pcg_mcg_16_advance_r(struct pcg_state_16* rng, uint16_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, 0u);
+ }
+
+ inline void pcg_unique_16_step_r(struct pcg_state_16* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16
+ + (uint16_t)(((intptr_t)rng) | 1u);
+ }
+
+ inline void pcg_unique_16_advance_r(struct pcg_state_16* rng, uint16_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16,
+ (uint16_t)(((intptr_t)rng) | 1u));
+ }
+
+ inline void pcg_setseq_16_step_r(struct pcg_state_setseq_16* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16 + rng->inc;
+ }
+
+ inline void pcg_setseq_16_advance_r(struct pcg_state_setseq_16* rng,
+ uint16_t delta)
+ {
+ rng->state = pcg_advance_lcg_16(rng->state, delta,
+ PCG_DEFAULT_MULTIPLIER_16, rng->inc);
+ }
+
+ inline void pcg_oneseq_32_step_r(struct pcg_state_32* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32
+ + PCG_DEFAULT_INCREMENT_32;
+ }
+
+ inline void pcg_oneseq_32_advance_r(struct pcg_state_32* rng, uint32_t delta)
+ {
+ rng->state = pcg_advance_lcg_32(
+ rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, PCG_DEFAULT_INCREMENT_32);
+ }
+
+ inline void pcg_mcg_32_step_r(struct pcg_state_32* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32;
+ }
+
+ inline void pcg_mcg_32_advance_r(struct pcg_state_32* rng, uint32_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, 0u);
+ }
+
+ inline void pcg_unique_32_step_r(struct pcg_state_32* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32
+ + (uint32_t)(((intptr_t)rng) | 1u);
+ }
+
+ inline void pcg_unique_32_advance_r(struct pcg_state_32* rng, uint32_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32,
+ (uint32_t)(((intptr_t)rng) | 1u));
+ }
+
+ inline void pcg_setseq_32_step_r(struct pcg_state_setseq_32* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32 + rng->inc;
+ }
+
+ inline void pcg_setseq_32_advance_r(struct pcg_state_setseq_32* rng,
+ uint32_t delta)
+ {
+ rng->state = pcg_advance_lcg_32(rng->state, delta,
+ PCG_DEFAULT_MULTIPLIER_32, rng->inc);
+ }
+
+ inline void pcg_oneseq_64_step_r(struct pcg_state_64* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64
+ + PCG_DEFAULT_INCREMENT_64;
+ }
+
+ inline void pcg_oneseq_64_advance_r(struct pcg_state_64* rng, uint64_t delta)
+ {
+ rng->state = pcg_advance_lcg_64(
+ rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, PCG_DEFAULT_INCREMENT_64);
+ }
+
+ inline void pcg_mcg_64_step_r(struct pcg_state_64* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64;
+ }
+
+ inline void pcg_mcg_64_advance_r(struct pcg_state_64* rng, uint64_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, 0u);
+ }
+
+ inline void pcg_unique_64_step_r(struct pcg_state_64* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64
+ + (uint64_t)(((intptr_t)rng) | 1u);
+ }
+
+ inline void pcg_unique_64_advance_r(struct pcg_state_64* rng, uint64_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64,
+ (uint64_t)(((intptr_t)rng) | 1u));
+ }
+
+ inline void pcg_setseq_64_step_r(struct pcg_state_setseq_64* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 + rng->inc;
+ }
+
+ inline void pcg_setseq_64_advance_r(struct pcg_state_setseq_64* rng,
+ uint64_t delta)
+ {
+ rng->state = pcg_advance_lcg_64(rng->state, delta,
+ PCG_DEFAULT_MULTIPLIER_64, rng->inc);
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_oneseq_128_step_r(struct pcg_state_128* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128
+ + PCG_DEFAULT_INCREMENT_128;
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_oneseq_128_advance_r(struct pcg_state_128* rng, pcg128_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_128(rng->state, delta, PCG_DEFAULT_MULTIPLIER_128,
+ PCG_DEFAULT_INCREMENT_128);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_mcg_128_step_r(struct pcg_state_128* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128;
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_mcg_128_advance_r(struct pcg_state_128* rng, pcg128_t delta)
+ {
+ rng->state = pcg_advance_lcg_128(rng->state, delta,
+ PCG_DEFAULT_MULTIPLIER_128, 0u);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_unique_128_step_r(struct pcg_state_128* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128
+ + (pcg128_t)(((intptr_t)rng) | 1u);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_unique_128_advance_r(struct pcg_state_128* rng, pcg128_t delta)
+ {
+ rng->state
+ = pcg_advance_lcg_128(rng->state, delta, PCG_DEFAULT_MULTIPLIER_128,
+ (pcg128_t)(((intptr_t)rng) | 1u));
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_setseq_128_step_r(struct pcg_state_setseq_128* rng)
+ {
+ rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128 + rng->inc;
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_setseq_128_advance_r(struct pcg_state_setseq_128* rng,
+ pcg128_t delta)
+ {
+ rng->state = pcg_advance_lcg_128(rng->state, delta,
+ PCG_DEFAULT_MULTIPLIER_128, rng->inc);
+ }
+#endif
+
+ /* Functions to seed the RNG state, one version for each size and each
+ * style. Unlike the step functions, regular users can and should call
+ * these functions.
+ */
+
+ inline void pcg_oneseq_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate)
+ {
+ rng->state = 0U;
+ pcg_oneseq_8_step_r(rng);
+ rng->state += initstate;
+ pcg_oneseq_8_step_r(rng);
+ }
+
+ inline void pcg_mcg_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate)
+ {
+ rng->state = initstate | 1u;
+ }
+
+ inline void pcg_unique_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate)
+ {
+ rng->state = 0U;
+ pcg_unique_8_step_r(rng);
+ rng->state += initstate;
+ pcg_unique_8_step_r(rng);
+ }
+
+ inline void pcg_setseq_8_srandom_r(struct pcg_state_setseq_8* rng,
+ uint8_t initstate, uint8_t initseq)
+ {
+ rng->state = 0U;
+ rng->inc = (initseq << 1u) | 1u;
+ pcg_setseq_8_step_r(rng);
+ rng->state += initstate;
+ pcg_setseq_8_step_r(rng);
+ }
+
+ inline void pcg_oneseq_16_srandom_r(struct pcg_state_16* rng,
+ uint16_t initstate)
+ {
+ rng->state = 0U;
+ pcg_oneseq_16_step_r(rng);
+ rng->state += initstate;
+ pcg_oneseq_16_step_r(rng);
+ }
+
+ inline void pcg_mcg_16_srandom_r(struct pcg_state_16* rng, uint16_t initstate)
+ {
+ rng->state = initstate | 1u;
+ }
+
+ inline void pcg_unique_16_srandom_r(struct pcg_state_16* rng,
+ uint16_t initstate)
+ {
+ rng->state = 0U;
+ pcg_unique_16_step_r(rng);
+ rng->state += initstate;
+ pcg_unique_16_step_r(rng);
+ }
+
+ inline void pcg_setseq_16_srandom_r(struct pcg_state_setseq_16* rng,
+ uint16_t initstate, uint16_t initseq)
+ {
+ rng->state = 0U;
+ rng->inc = (initseq << 1u) | 1u;
+ pcg_setseq_16_step_r(rng);
+ rng->state += initstate;
+ pcg_setseq_16_step_r(rng);
+ }
+
+ inline void pcg_oneseq_32_srandom_r(struct pcg_state_32* rng,
+ uint32_t initstate)
+ {
+ rng->state = 0U;
+ pcg_oneseq_32_step_r(rng);
+ rng->state += initstate;
+ pcg_oneseq_32_step_r(rng);
+ }
+
+ inline void pcg_mcg_32_srandom_r(struct pcg_state_32* rng, uint32_t initstate)
+ {
+ rng->state = initstate | 1u;
+ }
+
+ inline void pcg_unique_32_srandom_r(struct pcg_state_32* rng,
+ uint32_t initstate)
+ {
+ rng->state = 0U;
+ pcg_unique_32_step_r(rng);
+ rng->state += initstate;
+ pcg_unique_32_step_r(rng);
+ }
+
+ inline void pcg_setseq_32_srandom_r(struct pcg_state_setseq_32* rng,
+ uint32_t initstate, uint32_t initseq)
+ {
+ rng->state = 0U;
+ rng->inc = (initseq << 1u) | 1u;
+ pcg_setseq_32_step_r(rng);
+ rng->state += initstate;
+ pcg_setseq_32_step_r(rng);
+ }
+
+ inline void pcg_oneseq_64_srandom_r(struct pcg_state_64* rng,
+ uint64_t initstate)
+ {
+ rng->state = 0U;
+ pcg_oneseq_64_step_r(rng);
+ rng->state += initstate;
+ pcg_oneseq_64_step_r(rng);
+ }
+
+ inline void pcg_mcg_64_srandom_r(struct pcg_state_64* rng, uint64_t initstate)
+ {
+ rng->state = initstate | 1u;
+ }
+
+ inline void pcg_unique_64_srandom_r(struct pcg_state_64* rng,
+ uint64_t initstate)
+ {
+ rng->state = 0U;
+ pcg_unique_64_step_r(rng);
+ rng->state += initstate;
+ pcg_unique_64_step_r(rng);
+ }
+
+ inline void pcg_setseq_64_srandom_r(struct pcg_state_setseq_64* rng,
+ uint64_t initstate, uint64_t initseq)
+ {
+ rng->state = 0U;
+ rng->inc = (initseq << 1u) | 1u;
+ pcg_setseq_64_step_r(rng);
+ rng->state += initstate;
+ pcg_setseq_64_step_r(rng);
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_oneseq_128_srandom_r(struct pcg_state_128* rng,
+ pcg128_t initstate)
+ {
+ rng->state = 0U;
+ pcg_oneseq_128_step_r(rng);
+ rng->state += initstate;
+ pcg_oneseq_128_step_r(rng);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_mcg_128_srandom_r(struct pcg_state_128* rng, pcg128_t initstate)
+ {
+ rng->state = initstate | 1u;
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_unique_128_srandom_r(struct pcg_state_128* rng,
+ pcg128_t initstate)
+ {
+ rng->state = 0U;
+ pcg_unique_128_step_r(rng);
+ rng->state += initstate;
+ pcg_unique_128_step_r(rng);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline void pcg_setseq_128_srandom_r(struct pcg_state_setseq_128* rng,
+ pcg128_t initstate, pcg128_t initseq)
+ {
+ rng->state = 0U;
+ rng->inc = (initseq << 1u) | 1u;
+ pcg_setseq_128_step_r(rng);
+ rng->state += initstate;
+ pcg_setseq_128_step_r(rng);
+ }
+#endif
+
+ /* Now, finally we create each of the individual generators. We provide
+ * a random_r function that provides a random number of the appropriate
+ * type (using the full range of the type) and a boundedrand_r version
+ * that provides
+ *
+ * Implementation notes for boundedrand_r:
+ *
+ * To avoid bias, we need to make the range of the RNG a multiple of
+ * bound, which we do by dropping output less than a threshold.
+ * Let's consider a 32-bit case... A naive scheme to calculate the
+ * threshold would be to do
+ *
+ * uint32_t threshold = 0x100000000ull % bound;
+ *
+ * but 64-bit div/mod is slower than 32-bit div/mod (especially on
+ * 32-bit platforms). In essence, we do
+ *
+ * uint32_t threshold = (0x100000000ull-bound) % bound;
+ *
+ * because this version will calculate the same modulus, but the LHS
+ * value is less than 2^32.
+ *
+ * (Note that using modulo is only wise for good RNGs, poorer RNGs
+ * such as raw LCGs do better using a technique based on division.)
+ * Empricical tests show that division is preferable to modulus for
+ * reducting the range of an RNG. It's faster, and sometimes it can
+ * even be statistically prefereable.
+ */
+
+ /* Generation functions for XSH RS */
+
+ inline uint8_t pcg_oneseq_16_xsh_rs_8_random_r(struct pcg_state_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_oneseq_16_step_r(rng);
+ return pcg_output_xsh_rs_16_8(oldstate);
+ }
+
+ inline uint8_t pcg_oneseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_oneseq_16_xsh_rs_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t pcg_oneseq_32_xsh_rs_16_random_r(struct pcg_state_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_oneseq_32_step_r(rng);
+ return pcg_output_xsh_rs_32_16(oldstate);
+ }
+
+ inline uint16_t pcg_oneseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_oneseq_32_xsh_rs_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t pcg_oneseq_64_xsh_rs_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_oneseq_64_step_r(rng);
+ return pcg_output_xsh_rs_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_oneseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_oneseq_64_xsh_rs_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_oneseq_128_xsh_rs_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_oneseq_128_step_r(rng);
+ return pcg_output_xsh_rs_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_oneseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_oneseq_128_xsh_rs_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint8_t pcg_unique_16_xsh_rs_8_random_r(struct pcg_state_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_unique_16_step_r(rng);
+ return pcg_output_xsh_rs_16_8(oldstate);
+ }
+
+ inline uint8_t pcg_unique_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_unique_16_xsh_rs_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t pcg_unique_32_xsh_rs_16_random_r(struct pcg_state_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_unique_32_step_r(rng);
+ return pcg_output_xsh_rs_32_16(oldstate);
+ }
+
+ inline uint16_t pcg_unique_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_unique_32_xsh_rs_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t pcg_unique_64_xsh_rs_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_unique_64_step_r(rng);
+ return pcg_output_xsh_rs_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_unique_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_unique_64_xsh_rs_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_unique_128_xsh_rs_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_unique_128_step_r(rng);
+ return pcg_output_xsh_rs_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_unique_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_unique_128_xsh_rs_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint8_t pcg_setseq_16_xsh_rs_8_random_r(struct pcg_state_setseq_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_setseq_16_step_r(rng);
+ return pcg_output_xsh_rs_16_8(oldstate);
+ }
+
+ inline uint8_t
+ pcg_setseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_setseq_16* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_setseq_16_xsh_rs_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t
+ pcg_setseq_32_xsh_rs_16_random_r(struct pcg_state_setseq_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_setseq_32_step_r(rng);
+ return pcg_output_xsh_rs_32_16(oldstate);
+ }
+
+ inline uint16_t
+ pcg_setseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_setseq_32* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_setseq_32_xsh_rs_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t
+ pcg_setseq_64_xsh_rs_32_random_r(struct pcg_state_setseq_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_setseq_64_step_r(rng);
+ return pcg_output_xsh_rs_64_32(oldstate);
+ }
+
+ inline uint32_t
+ pcg_setseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_setseq_64_xsh_rs_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_setseq_128_xsh_rs_64_random_r(struct pcg_state_setseq_128* rng)
+ {
+ pcg_setseq_128_step_r(rng);
+ return pcg_output_xsh_rs_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_setseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_setseq_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_setseq_128_xsh_rs_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint8_t pcg_mcg_16_xsh_rs_8_random_r(struct pcg_state_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_mcg_16_step_r(rng);
+ return pcg_output_xsh_rs_16_8(oldstate);
+ }
+
+ inline uint8_t pcg_mcg_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_mcg_16_xsh_rs_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t pcg_mcg_32_xsh_rs_16_random_r(struct pcg_state_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_mcg_32_step_r(rng);
+ return pcg_output_xsh_rs_32_16(oldstate);
+ }
+
+ inline uint16_t pcg_mcg_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_mcg_32_xsh_rs_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t pcg_mcg_64_xsh_rs_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_mcg_64_step_r(rng);
+ return pcg_output_xsh_rs_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_mcg_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_mcg_64_xsh_rs_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_mcg_128_xsh_rs_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_mcg_128_step_r(rng);
+ return pcg_output_xsh_rs_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_mcg_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_mcg_128_xsh_rs_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ /* Generation functions for XSH RR */
+
+ inline uint8_t pcg_oneseq_16_xsh_rr_8_random_r(struct pcg_state_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_oneseq_16_step_r(rng);
+ return pcg_output_xsh_rr_16_8(oldstate);
+ }
+
+ inline uint8_t pcg_oneseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_oneseq_16_xsh_rr_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t pcg_oneseq_32_xsh_rr_16_random_r(struct pcg_state_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_oneseq_32_step_r(rng);
+ return pcg_output_xsh_rr_32_16(oldstate);
+ }
+
+ inline uint16_t pcg_oneseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_oneseq_32_xsh_rr_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t pcg_oneseq_64_xsh_rr_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_oneseq_64_step_r(rng);
+ return pcg_output_xsh_rr_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_oneseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_oneseq_64_xsh_rr_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_oneseq_128_xsh_rr_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_oneseq_128_step_r(rng);
+ return pcg_output_xsh_rr_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_oneseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_oneseq_128_xsh_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint8_t pcg_unique_16_xsh_rr_8_random_r(struct pcg_state_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_unique_16_step_r(rng);
+ return pcg_output_xsh_rr_16_8(oldstate);
+ }
+
+ inline uint8_t pcg_unique_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_unique_16_xsh_rr_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t pcg_unique_32_xsh_rr_16_random_r(struct pcg_state_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_unique_32_step_r(rng);
+ return pcg_output_xsh_rr_32_16(oldstate);
+ }
+
+ inline uint16_t pcg_unique_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_unique_32_xsh_rr_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t pcg_unique_64_xsh_rr_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_unique_64_step_r(rng);
+ return pcg_output_xsh_rr_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_unique_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_unique_64_xsh_rr_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_unique_128_xsh_rr_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_unique_128_step_r(rng);
+ return pcg_output_xsh_rr_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_unique_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_unique_128_xsh_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint8_t pcg_setseq_16_xsh_rr_8_random_r(struct pcg_state_setseq_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_setseq_16_step_r(rng);
+ return pcg_output_xsh_rr_16_8(oldstate);
+ }
+
+ inline uint8_t
+ pcg_setseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_setseq_16* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_setseq_16_xsh_rr_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t
+ pcg_setseq_32_xsh_rr_16_random_r(struct pcg_state_setseq_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_setseq_32_step_r(rng);
+ return pcg_output_xsh_rr_32_16(oldstate);
+ }
+
+ inline uint16_t
+ pcg_setseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_setseq_32* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_setseq_32_xsh_rr_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t
+ pcg_setseq_64_xsh_rr_32_random_r(struct pcg_state_setseq_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_setseq_64_step_r(rng);
+ return pcg_output_xsh_rr_64_32(oldstate);
+ }
+
+ inline uint32_t
+ pcg_setseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_setseq_64_xsh_rr_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_setseq_128_xsh_rr_64_random_r(struct pcg_state_setseq_128* rng)
+ {
+ pcg_setseq_128_step_r(rng);
+ return pcg_output_xsh_rr_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_setseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_setseq_128_xsh_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint8_t pcg_mcg_16_xsh_rr_8_random_r(struct pcg_state_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_mcg_16_step_r(rng);
+ return pcg_output_xsh_rr_16_8(oldstate);
+ }
+
+ inline uint8_t pcg_mcg_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_mcg_16_xsh_rr_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t pcg_mcg_32_xsh_rr_16_random_r(struct pcg_state_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_mcg_32_step_r(rng);
+ return pcg_output_xsh_rr_32_16(oldstate);
+ }
+
+ inline uint16_t pcg_mcg_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_mcg_32_xsh_rr_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t pcg_mcg_64_xsh_rr_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_mcg_64_step_r(rng);
+ return pcg_output_xsh_rr_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_mcg_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_mcg_64_xsh_rr_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_mcg_128_xsh_rr_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_mcg_128_step_r(rng);
+ return pcg_output_xsh_rr_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_mcg_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_mcg_128_xsh_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ /* Generation functions for RXS M XS (no MCG versions because they
+ * don't make sense when you want to use the entire state)
+ */
+
+ inline uint8_t pcg_oneseq_8_rxs_m_xs_8_random_r(struct pcg_state_8* rng)
+ {
+ uint8_t oldstate = rng->state;
+ pcg_oneseq_8_step_r(rng);
+ return pcg_output_rxs_m_xs_8_8(oldstate);
+ }
+
+ inline uint8_t pcg_oneseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_8* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_oneseq_8_rxs_m_xs_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t pcg_oneseq_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_oneseq_16_step_r(rng);
+ return pcg_output_rxs_m_xs_16_16(oldstate);
+ }
+
+ inline uint16_t
+ pcg_oneseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_oneseq_16_rxs_m_xs_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t pcg_oneseq_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_oneseq_32_step_r(rng);
+ return pcg_output_rxs_m_xs_32_32(oldstate);
+ }
+
+ inline uint32_t
+ pcg_oneseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_oneseq_32_rxs_m_xs_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint64_t pcg_oneseq_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_oneseq_64_step_r(rng);
+ return pcg_output_rxs_m_xs_64_64(oldstate);
+ }
+
+ inline uint64_t
+ pcg_oneseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_oneseq_64_rxs_m_xs_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t pcg_oneseq_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng)
+ {
+ pcg_oneseq_128_step_r(rng);
+ return pcg_output_rxs_m_xs_128_128(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t
+ pcg_oneseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng,
+ pcg128_t bound)
+ {
+ pcg128_t threshold = -bound % bound;
+ for (;;) {
+ pcg128_t r = pcg_oneseq_128_rxs_m_xs_128_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint16_t pcg_unique_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_unique_16_step_r(rng);
+ return pcg_output_rxs_m_xs_16_16(oldstate);
+ }
+
+ inline uint16_t
+ pcg_unique_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_unique_16_rxs_m_xs_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t pcg_unique_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_unique_32_step_r(rng);
+ return pcg_output_rxs_m_xs_32_32(oldstate);
+ }
+
+ inline uint32_t
+ pcg_unique_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_unique_32_rxs_m_xs_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint64_t pcg_unique_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_unique_64_step_r(rng);
+ return pcg_output_rxs_m_xs_64_64(oldstate);
+ }
+
+ inline uint64_t
+ pcg_unique_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_unique_64_rxs_m_xs_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t pcg_unique_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng)
+ {
+ pcg_unique_128_step_r(rng);
+ return pcg_output_rxs_m_xs_128_128(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t
+ pcg_unique_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng,
+ pcg128_t bound)
+ {
+ pcg128_t threshold = -bound % bound;
+ for (;;) {
+ pcg128_t r = pcg_unique_128_rxs_m_xs_128_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint8_t pcg_setseq_8_rxs_m_xs_8_random_r(struct pcg_state_setseq_8* rng)
+ {
+ uint8_t oldstate = rng->state;
+ pcg_setseq_8_step_r(rng);
+ return pcg_output_rxs_m_xs_8_8(oldstate);
+ }
+
+ inline uint8_t
+ pcg_setseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_setseq_8* rng,
+ uint8_t bound)
+ {
+ uint8_t threshold = ((uint8_t)(-bound)) % bound;
+ for (;;) {
+ uint8_t r = pcg_setseq_8_rxs_m_xs_8_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint16_t
+ pcg_setseq_16_rxs_m_xs_16_random_r(struct pcg_state_setseq_16* rng)
+ {
+ uint16_t oldstate = rng->state;
+ pcg_setseq_16_step_r(rng);
+ return pcg_output_rxs_m_xs_16_16(oldstate);
+ }
+
+ inline uint16_t
+ pcg_setseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_setseq_16* rng,
+ uint16_t bound)
+ {
+ uint16_t threshold = ((uint16_t)(-bound)) % bound;
+ for (;;) {
+ uint16_t r = pcg_setseq_16_rxs_m_xs_16_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint32_t
+ pcg_setseq_32_rxs_m_xs_32_random_r(struct pcg_state_setseq_32* rng)
+ {
+ uint32_t oldstate = rng->state;
+ pcg_setseq_32_step_r(rng);
+ return pcg_output_rxs_m_xs_32_32(oldstate);
+ }
+
+ inline uint32_t
+ pcg_setseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_setseq_32* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_setseq_32_rxs_m_xs_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+ inline uint64_t
+ pcg_setseq_64_rxs_m_xs_64_random_r(struct pcg_state_setseq_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_setseq_64_step_r(rng);
+ return pcg_output_rxs_m_xs_64_64(oldstate);
+ }
+
+ inline uint64_t
+ pcg_setseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_setseq_64_rxs_m_xs_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t
+ pcg_setseq_128_rxs_m_xs_128_random_r(struct pcg_state_setseq_128* rng)
+ {
+ pcg_setseq_128_step_r(rng);
+ return pcg_output_rxs_m_xs_128_128(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t
+ pcg_setseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_setseq_128* rng,
+ pcg128_t bound)
+ {
+ pcg128_t threshold = -bound % bound;
+ for (;;) {
+ pcg128_t r = pcg_setseq_128_rxs_m_xs_128_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ /* Generation functions for XSL RR (only defined for "large" types) */
+
+ inline uint32_t pcg_oneseq_64_xsl_rr_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_oneseq_64_step_r(rng);
+ return pcg_output_xsl_rr_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_oneseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_oneseq_64_xsl_rr_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_oneseq_128_xsl_rr_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_oneseq_128_step_r(rng);
+ return pcg_output_xsl_rr_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_oneseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_oneseq_128_xsl_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint32_t pcg_unique_64_xsl_rr_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_unique_64_step_r(rng);
+ return pcg_output_xsl_rr_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_unique_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_unique_64_xsl_rr_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_unique_128_xsl_rr_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_unique_128_step_r(rng);
+ return pcg_output_xsl_rr_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_unique_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_unique_128_xsl_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint32_t
+ pcg_setseq_64_xsl_rr_32_random_r(struct pcg_state_setseq_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_setseq_64_step_r(rng);
+ return pcg_output_xsl_rr_64_32(oldstate);
+ }
+
+ inline uint32_t
+ pcg_setseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_setseq_64_xsl_rr_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_setseq_128_xsl_rr_64_random_r(struct pcg_state_setseq_128* rng)
+ {
+ pcg_setseq_128_step_r(rng);
+ return pcg_output_xsl_rr_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t
+ pcg_setseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_setseq_128_xsl_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint32_t pcg_mcg_64_xsl_rr_32_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_mcg_64_step_r(rng);
+ return pcg_output_xsl_rr_64_32(oldstate);
+ }
+
+ inline uint32_t pcg_mcg_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng,
+ uint32_t bound)
+ {
+ uint32_t threshold = -bound % bound;
+ for (;;) {
+ uint32_t r = pcg_mcg_64_xsl_rr_32_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_mcg_128_xsl_rr_64_random_r(struct pcg_state_128* rng)
+ {
+ pcg_mcg_128_step_r(rng);
+ return pcg_output_xsl_rr_128_64(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline uint64_t pcg_mcg_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_mcg_128_xsl_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ /* Generation functions for XSL RR RR (only defined for "large" types) */
+
+ inline uint64_t pcg_oneseq_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_oneseq_64_step_r(rng);
+ return pcg_output_xsl_rr_rr_64_64(oldstate);
+ }
+
+ inline uint64_t
+ pcg_oneseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_oneseq_64_xsl_rr_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t pcg_oneseq_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng)
+ {
+ pcg_oneseq_128_step_r(rng);
+ return pcg_output_xsl_rr_rr_128_128(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t
+ pcg_oneseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng,
+ pcg128_t bound)
+ {
+ pcg128_t threshold = -bound % bound;
+ for (;;) {
+ pcg128_t r = pcg_oneseq_128_xsl_rr_rr_128_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint64_t pcg_unique_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_unique_64_step_r(rng);
+ return pcg_output_xsl_rr_rr_64_64(oldstate);
+ }
+
+ inline uint64_t
+ pcg_unique_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_unique_64_xsl_rr_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t pcg_unique_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng)
+ {
+ pcg_unique_128_step_r(rng);
+ return pcg_output_xsl_rr_rr_128_128(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t
+ pcg_unique_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng,
+ pcg128_t bound)
+ {
+ pcg128_t threshold = -bound % bound;
+ for (;;) {
+ pcg128_t r = pcg_unique_128_xsl_rr_rr_128_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ inline uint64_t
+ pcg_setseq_64_xsl_rr_rr_64_random_r(struct pcg_state_setseq_64* rng)
+ {
+ uint64_t oldstate = rng->state;
+ pcg_setseq_64_step_r(rng);
+ return pcg_output_xsl_rr_rr_64_64(oldstate);
+ }
+
+ inline uint64_t
+ pcg_setseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_setseq_64* rng,
+ uint64_t bound)
+ {
+ uint64_t threshold = -bound % bound;
+ for (;;) {
+ uint64_t r = pcg_setseq_64_xsl_rr_rr_64_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t
+ pcg_setseq_128_xsl_rr_rr_128_random_r(struct pcg_state_setseq_128* rng)
+ {
+ pcg_setseq_128_step_r(rng);
+ return pcg_output_xsl_rr_rr_128_128(rng->state);
+ }
+#endif
+
+#if PCG_HAS_128BIT_OPS
+ inline pcg128_t
+ pcg_setseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_setseq_128* rng,
+ pcg128_t bound)
+ {
+ pcg128_t threshold = -bound % bound;
+ for (;;) {
+ pcg128_t r = pcg_setseq_128_xsl_rr_rr_128_random_r(rng);
+ if (r >= threshold)
+ return r % bound;
+ }
+ }
+#endif
+
+ //// Typedefs
+ typedef struct pcg_state_setseq_64 pcg32_random_t;
+ typedef struct pcg_state_64 pcg32s_random_t;
+ typedef struct pcg_state_64 pcg32u_random_t;
+ typedef struct pcg_state_64 pcg32f_random_t;
+ //// random_r
+#define pcg32_random_r pcg_setseq_64_xsh_rr_32_random_r
+#define pcg32s_random_r pcg_oneseq_64_xsh_rr_32_random_r
+#define pcg32u_random_r pcg_unique_64_xsh_rr_32_random_r
+#define pcg32f_random_r pcg_mcg_64_xsh_rs_32_random_r
+ //// boundedrand_r
+#define pcg32_boundedrand_r pcg_setseq_64_xsh_rr_32_boundedrand_r
+#define pcg32s_boundedrand_r pcg_oneseq_64_xsh_rr_32_boundedrand_r
+#define pcg32u_boundedrand_r pcg_unique_64_xsh_rr_32_boundedrand_r
+#define pcg32f_boundedrand_r pcg_mcg_64_xsh_rs_32_boundedrand_r
+ //// srandom_r
+#define pcg32_srandom_r pcg_setseq_64_srandom_r
+#define pcg32s_srandom_r pcg_oneseq_64_srandom_r
+#define pcg32u_srandom_r pcg_unique_64_srandom_r
+#define pcg32f_srandom_r pcg_mcg_64_srandom_r
+ //// advance_r
+#define pcg32_advance_r pcg_setseq_64_advance_r
+#define pcg32s_advance_r pcg_oneseq_64_advance_r
+#define pcg32u_advance_r pcg_unique_64_advance_r
+#define pcg32f_advance_r pcg_mcg_64_advance_r
+
+#if PCG_HAS_128BIT_OPS
+ //// Typedefs
+ typedef struct pcg_state_setseq_128 pcg64_random_t;
+ typedef struct pcg_state_128 pcg64s_random_t;
+ typedef struct pcg_state_128 pcg64u_random_t;
+ typedef struct pcg_state_128 pcg64f_random_t;
+ //// random_r
+#define pcg64_random_r pcg_setseq_128_xsl_rr_64_random_r
+#define pcg64s_random_r pcg_oneseq_128_xsl_rr_64_random_r
+#define pcg64u_random_r pcg_unique_128_xsl_rr_64_random_r
+#define pcg64f_random_r pcg_mcg_128_xsl_rr_64_random_r
+ //// boundedrand_r
+#define pcg64_boundedrand_r pcg_setseq_128_xsl_rr_64_boundedrand_r
+#define pcg64s_boundedrand_r pcg_oneseq_128_xsl_rr_64_boundedrand_r
+#define pcg64u_boundedrand_r pcg_unique_128_xsl_rr_64_boundedrand_r
+#define pcg64f_boundedrand_r pcg_mcg_128_xsl_rr_64_boundedrand_r
+ //// srandom_r
+#define pcg64_srandom_r pcg_setseq_128_srandom_r
+#define pcg64s_srandom_r pcg_oneseq_128_srandom_r
+#define pcg64u_srandom_r pcg_unique_128_srandom_r
+#define pcg64f_srandom_r pcg_mcg_128_srandom_r
+ //// advance_r
+#define pcg64_advance_r pcg_setseq_128_advance_r
+#define pcg64s_advance_r pcg_oneseq_128_advance_r
+#define pcg64u_advance_r pcg_unique_128_advance_r
+#define pcg64f_advance_r pcg_mcg_128_advance_r
+#endif
+
+ //// Typedefs
+ typedef struct pcg_state_8 pcg8si_random_t;
+ typedef struct pcg_state_16 pcg16si_random_t;
+ typedef struct pcg_state_32 pcg32si_random_t;
+ typedef struct pcg_state_64 pcg64si_random_t;
+ //// random_r
+#define pcg8si_random_r pcg_oneseq_8_rxs_m_xs_8_random_r
+#define pcg16si_random_r pcg_oneseq_16_rxs_m_xs_16_random_r
+#define pcg32si_random_r pcg_oneseq_32_rxs_m_xs_32_random_r
+#define pcg64si_random_r pcg_oneseq_64_rxs_m_xs_64_random_r
+ //// boundedrand_r
+#define pcg8si_boundedrand_r pcg_oneseq_8_rxs_m_xs_8_boundedrand_r
+#define pcg16si_boundedrand_r pcg_oneseq_16_rxs_m_xs_16_boundedrand_r
+#define pcg32si_boundedrand_r pcg_oneseq_32_rxs_m_xs_32_boundedrand_r
+#define pcg64si_boundedrand_r pcg_oneseq_64_rxs_m_xs_64_boundedrand_r
+ //// srandom_r
+#define pcg8si_srandom_r pcg_oneseq_8_srandom_r
+#define pcg16si_srandom_r pcg_oneseq_16_srandom_r
+#define pcg32si_srandom_r pcg_oneseq_32_srandom_r
+#define pcg64si_srandom_r pcg_oneseq_64_srandom_r
+ //// advance_r
+#define pcg8si_advance_r pcg_oneseq_8_advance_r
+#define pcg16si_advance_r pcg_oneseq_16_advance_r
+#define pcg32si_advance_r pcg_oneseq_32_advance_r
+#define pcg64si_advance_r pcg_oneseq_64_advance_r
+
+#if PCG_HAS_128BIT_OPS
+ typedef struct pcg_state_128 pcg128si_random_t;
+#define pcg128si_random_r pcg_oneseq_128_rxs_m_xs_128_random_r
+#define pcg128si_boundedrand_r pcg_oneseq_128_rxs_m_xs_128_boundedrand_r
+#define pcg128si_srandom_r pcg_oneseq_128_srandom_r
+#define pcg128si_advance_r pcg_oneseq_128_advance_r
+#endif
+
+ //// Typedefs
+ typedef struct pcg_state_setseq_8 pcg8i_random_t;
+ typedef struct pcg_state_setseq_16 pcg16i_random_t;
+ typedef struct pcg_state_setseq_32 pcg32i_random_t;
+ typedef struct pcg_state_setseq_64 pcg64i_random_t;
+ //// random_r
+#define pcg8i_random_r pcg_setseq_8_rxs_m_xs_8_random_r
+#define pcg16i_random_r pcg_setseq_16_rxs_m_xs_16_random_r
+#define pcg32i_random_r pcg_setseq_32_rxs_m_xs_32_random_r
+#define pcg64i_random_r pcg_setseq_64_rxs_m_xs_64_random_r
+ //// boundedrand_r
+#define pcg8i_boundedrand_r pcg_setseq_8_rxs_m_xs_8_boundedrand_r
+#define pcg16i_boundedrand_r pcg_setseq_16_rxs_m_xs_16_boundedrand_r
+#define pcg32i_boundedrand_r pcg_setseq_32_rxs_m_xs_32_boundedrand_r
+#define pcg64i_boundedrand_r pcg_setseq_64_rxs_m_xs_64_boundedrand_r
+ //// srandom_r
+#define pcg8i_srandom_r pcg_setseq_8_srandom_r
+#define pcg16i_srandom_r pcg_setseq_16_srandom_r
+#define pcg32i_srandom_r pcg_setseq_32_srandom_r
+#define pcg64i_srandom_r pcg_setseq_64_srandom_r
+ //// advance_r
+#define pcg8i_advance_r pcg_setseq_8_advance_r
+#define pcg16i_advance_r pcg_setseq_16_advance_r
+#define pcg32i_advance_r pcg_setseq_32_advance_r
+#define pcg64i_advance_r pcg_setseq_64_advance_r
+
+#if PCG_HAS_128BIT_OPS
+ typedef struct pcg_state_setseq_128 pcg128i_random_t;
+#define pcg128i_random_r pcg_setseq_128_rxs_m_xs_128_random_r
+#define pcg128i_boundedrand_r pcg_setseq_128_rxs_m_xs_128_boundedrand_r
+#define pcg128i_srandom_r pcg_setseq_128_srandom_r
+#define pcg128i_advance_r pcg_setseq_128_advance_r
+#endif
+
+ extern uint32_t pcg32_random();
+ extern uint32_t pcg32_boundedrand(uint32_t bound);
+ extern void pcg32_srandom(uint64_t seed, uint64_t seq);
+ extern void pcg32_advance(uint64_t delta);
+
+#if PCG_HAS_128BIT_OPS
+ extern uint64_t pcg64_random();
+ extern uint64_t pcg64_boundedrand(uint64_t bound);
+ extern void pcg64_srandom(pcg128_t seed, pcg128_t seq);
+ extern void pcg64_advance(pcg128_t delta);
+#endif
+
+ /*
+ * Static initialization constants (if you can't call srandom for some
+ * bizarre reason).
+ */
+
+#define PCG32_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER
+#define PCG32U_INITIALIZER PCG_STATE_UNIQUE_64_INITIALIZER
+#define PCG32S_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER
+#define PCG32F_INITIALIZER PCG_STATE_MCG_64_INITIALIZER
+
+#if PCG_HAS_128BIT_OPS
+#define PCG64_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER
+#define PCG64U_INITIALIZER PCG_STATE_UNIQUE_128_INITIALIZER
+#define PCG64S_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER
+#define PCG64F_INITIALIZER PCG_STATE_MCG_128_INITIALIZER
+#endif
+
+#if PCG_HAS_128BIT_OPS
+#define PCG8SI_INITIALIZER PCG_STATE_ONESEQ_8_INITIALIZER
+#define PCG16SI_INITIALIZER PCG_STATE_ONESEQ_16_INITIALIZER
+#define PCG32SI_INITIALIZER PCG_STATE_ONESEQ_32_INITIALIZER
+#define PCG64SI_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER
+#define PCG128SI_INITIALIZER PCG_STATE_ONESEQ_128_INITIALIZER
+#endif
+
+#if PCG_HAS_128BIT_OPS
+#define PCG8I_INITIALIZER PCG_STATE_SETSEQ_8_INITIALIZER
+#define PCG16I_INITIALIZER PCG_STATE_SETSEQ_16_INITIALIZER
+#define PCG32I_INITIALIZER PCG_STATE_SETSEQ_32_INITIALIZER
+#define PCG64I_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER
+#define PCG128I_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER
+#endif
+
+#if __cplusplus
+}
+#endif
+
+#endif // PCG_VARIANTS_H_INCLUDED
+
diff --git a/src/haversine/listing_065.cpp b/src/haversine/listing_065.cpp
new file mode 100644
index 0000000..86e087c
--- /dev/null
+++ b/src/haversine/listing_065.cpp
@@ -0,0 +1,39 @@
+#include <math.h>
+
+static f64 Square(f64 A)
+{
+ f64 Result = (A*A);
+ return Result;
+}
+
+static f64 RadiansFromDegrees(f64 Degrees)
+{
+ f64 Result = 0.01745329251994329577 * Degrees;
+ return Result;
+}
+
+// NOTE(casey): EarthRadius is generally expected to be 6372.8
+static f64 ReferenceHaversine(f64 X0, f64 Y0, f64 X1, f64 Y1, f64 EarthRadius)
+{
+ /* NOTE(casey): This is not meant to be a "good" way to calculate the Haversine distance.
+ Instead, it attempts to follow, as closely as possible, the formula used in the real-world
+ question on which these homework exercises are loosely based.
+ */
+
+ f64 lat1 = Y0;
+ f64 lat2 = Y1;
+ f64 lon1 = X0;
+ f64 lon2 = X1;
+
+ f64 dLat = RadiansFromDegrees(lat2 - lat1);
+ f64 dLon = RadiansFromDegrees(lon2 - lon1);
+ lat1 = RadiansFromDegrees(lat1);
+ lat2 = RadiansFromDegrees(lat2);
+
+ f64 a = Square(sin(dLat/2.0)) + cos(lat1)*cos(lat2)*Square(sin(dLon/2));
+ f64 c = 2.0*asin(sqrt(a));
+
+ f64 Result = EarthRadius * c;
+
+ return Result;
+}
diff --git a/src/sim86/bin/generated/generated.cpp b/src/sim86/bin/generated/generated.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/sim86/bin/generated/generated.cpp
diff --git a/src/tmux.sh b/src/sim86/bin/tmux.sh
index 78845a9..78845a9 100755
--- a/src/tmux.sh
+++ b/src/sim86/bin/tmux.sh
diff --git a/src/build.sh b/src/sim86/build.sh
index 7726aee..74f6828 100755
--- a/src/build.sh
+++ b/src/sim86/build.sh
@@ -1,9 +1,9 @@
#!/bin/sh
-ThisDir="$(dirname "$(readlink -f "$0")")"
-cd "$ThisDir"
+cd "$(dirname "$(readlink -f "$0")")"
-mkdir -p ../build
+Build="../../build"
+mkdir -p "$Build"
mkdir -p generated
Compiler="clang"
@@ -30,12 +30,13 @@ WarningFlags="
printf '[metadata generation]\n'
$Compiler $CompilerFlags $WarningFlags \
- -o ../build/sim86_meta \
+ -o "$Build"/sim86_meta \
sim86_meta.c
-../build/sim86_meta ./sim86.mdesk > ./generated/generated.cpp
+"$Build"/sim86_meta ./sim86.mdesk > ./generated/generated.cpp
+printf '[debug mode]\n'
printf '[%s build]\n' "$Compiler"
Source="sim86.cpp"
$Compiler $CompilerFlags $WarningFlags \
- -o ../build/sim86 \
+ -o "$Build"/sim86 \
sim86.cpp
diff --git a/src/clocks_table.inl b/src/sim86/clocks_table.inl
index 2c07bb3..2c07bb3 100644
--- a/src/clocks_table.inl
+++ b/src/sim86/clocks_table.inl
diff --git a/src/generated/generated.cpp b/src/sim86/generated/generated.cpp
index 0f457a1..0f457a1 100644
--- a/src/generated/generated.cpp
+++ b/src/sim86/generated/generated.cpp
diff --git a/src/libs/metadesk/md.c b/src/sim86/libs/metadesk/md.c
index 6be1e69..6be1e69 100644
--- a/src/libs/metadesk/md.c
+++ b/src/sim86/libs/metadesk/md.c
diff --git a/src/libs/metadesk/md.h b/src/sim86/libs/metadesk/md.h
index faad8e3..faad8e3 100644
--- a/src/libs/metadesk/md.h
+++ b/src/sim86/libs/metadesk/md.h
diff --git a/src/libs/metadesk/md_stb_sprintf.h b/src/sim86/libs/metadesk/md_stb_sprintf.h
index 4758435..4758435 100644
--- a/src/libs/metadesk/md_stb_sprintf.h
+++ b/src/sim86/libs/metadesk/md_stb_sprintf.h
diff --git a/src/libs/reference_decoder/sim86.h b/src/sim86/libs/reference_decoder/sim86.h
index b065a0e..b065a0e 100644
--- a/src/libs/reference_decoder/sim86.h
+++ b/src/sim86/libs/reference_decoder/sim86.h
diff --git a/src/libs/reference_decoder/sim86_decode.cpp b/src/sim86/libs/reference_decoder/sim86_decode.cpp
index dc084d5..dc084d5 100644
--- a/src/libs/reference_decoder/sim86_decode.cpp
+++ b/src/sim86/libs/reference_decoder/sim86_decode.cpp
diff --git a/src/libs/reference_decoder/sim86_decode.h b/src/sim86/libs/reference_decoder/sim86_decode.h
index 534ce2d..534ce2d 100644
--- a/src/libs/reference_decoder/sim86_decode.h
+++ b/src/sim86/libs/reference_decoder/sim86_decode.h
diff --git a/src/libs/reference_decoder/sim86_instruction.cpp b/src/sim86/libs/reference_decoder/sim86_instruction.cpp
index 34fcf1f..34fcf1f 100644
--- a/src/libs/reference_decoder/sim86_instruction.cpp
+++ b/src/sim86/libs/reference_decoder/sim86_instruction.cpp
diff --git a/src/libs/reference_decoder/sim86_instruction.h b/src/sim86/libs/reference_decoder/sim86_instruction.h
index 191635a..191635a 100644
--- a/src/libs/reference_decoder/sim86_instruction.h
+++ b/src/sim86/libs/reference_decoder/sim86_instruction.h
diff --git a/src/libs/reference_decoder/sim86_instruction_table.cpp b/src/sim86/libs/reference_decoder/sim86_instruction_table.cpp
index be3ec82..be3ec82 100644
--- a/src/libs/reference_decoder/sim86_instruction_table.cpp
+++ b/src/sim86/libs/reference_decoder/sim86_instruction_table.cpp
diff --git a/src/libs/reference_decoder/sim86_instruction_table.h b/src/sim86/libs/reference_decoder/sim86_instruction_table.h
index ed8aea8..ed8aea8 100644
--- a/src/libs/reference_decoder/sim86_instruction_table.h
+++ b/src/sim86/libs/reference_decoder/sim86_instruction_table.h
diff --git a/src/libs/reference_decoder/sim86_instruction_table.inl b/src/sim86/libs/reference_decoder/sim86_instruction_table.inl
index 576c0f6..576c0f6 100644
--- a/src/libs/reference_decoder/sim86_instruction_table.inl
+++ b/src/sim86/libs/reference_decoder/sim86_instruction_table.inl
diff --git a/src/libs/reference_decoder/sim86_lib.cpp b/src/sim86/libs/reference_decoder/sim86_lib.cpp
index 6971eb2..6971eb2 100644
--- a/src/libs/reference_decoder/sim86_lib.cpp
+++ b/src/sim86/libs/reference_decoder/sim86_lib.cpp
diff --git a/src/libs/reference_decoder/sim86_memory.cpp b/src/sim86/libs/reference_decoder/sim86_memory.cpp
index 1d58ede..1d58ede 100644
--- a/src/libs/reference_decoder/sim86_memory.cpp
+++ b/src/sim86/libs/reference_decoder/sim86_memory.cpp
diff --git a/src/libs/reference_decoder/sim86_memory.h b/src/sim86/libs/reference_decoder/sim86_memory.h
index 4e790dc..4e790dc 100644
--- a/src/libs/reference_decoder/sim86_memory.h
+++ b/src/sim86/libs/reference_decoder/sim86_memory.h
diff --git a/src/libs/reference_decoder/sim86_text_table.cpp b/src/sim86/libs/reference_decoder/sim86_text_table.cpp
index e90a649..e90a649 100644
--- a/src/libs/reference_decoder/sim86_text_table.cpp
+++ b/src/sim86/libs/reference_decoder/sim86_text_table.cpp
diff --git a/src/sim86.cpp b/src/sim86/sim86.cpp
index 7c444bd..7c444bd 100644
--- a/src/sim86.cpp
+++ b/src/sim86/sim86.cpp
diff --git a/src/sim86.h b/src/sim86/sim86.h
index 24068e2..24068e2 100644
--- a/src/sim86.h
+++ b/src/sim86/sim86.h
diff --git a/src/sim86.mdesk b/src/sim86/sim86.mdesk
index 0635110..0635110 100644
--- a/src/sim86.mdesk
+++ b/src/sim86/sim86.mdesk
diff --git a/src/sim86_meta.c b/src/sim86/sim86_meta.c
index c8fe8f3..37fe0c3 100644
--- a/src/sim86_meta.c
+++ b/src/sim86/sim86_meta.c
@@ -1,3 +1,4 @@
+
#if __clang__
# define COMPILER_CLANG 1
#elif _MSC_VER
diff --git a/src/sim86_shared.h b/src/sim86/sim86_shared.h
index 7a54beb..7a54beb 100644
--- a/src/sim86_shared.h
+++ b/src/sim86/sim86_shared.h