/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuRandomDevice.cpp Date: 2021-9-3 Author: Reece ***/ #include #include "AuRandomDevice.hpp" namespace Aurora::RNG { static const double kDblEpsilon = 2.2204460492503131e-16; static thread_local char tlsScratchMemory[2048]; #define RNG_BYTES_PROLOGUE \ AuList rngBytes_; \ AuMemoryViewWrite rngBytes; #define RNG_BYTES_RESIZE(n) \ if (n * sizeof(AuUInt64) < AuArraySize(tlsScratchMemory)) \ { \ rngBytes = AuMemoryViewWrite(tlsScratchMemory).Take(n * sizeof(AuUInt64)); \ } \ else \ { \ rngBytes_.resize(n); \ rngBytes = rngBytes_; \ } #define RNG_BYTES_SIZE \ rngBytes.ToCount() RandomDevice::RandomDevice() : IO::Adapters::RandomStreamReader(AuUnsafeRaiiToShared(this)) { } RandomDevice::RandomDevice(const RandomDef &def) : IO::Adapters::RandomStreamReader(AuUnsafeRaiiToShared(this)) { this->Init(def); } void RandomDevice::Init(const RandomDef &def) { this->def_ = def; // Gross... if (!def.bSecure) { if (def.seed) { this->fast_ = AuMove(WELL_SeedRand(def.seed.value())); } else if (def.seed64) { this->fast_ = AuMove(WELL_SeedRand64(def.seed64.value())); } else if (def.seedMassive) { this->fast_ = AuMove(WELL_SeedRandBig64(def.seedMassive.value())); } else { RNG::RngFillArray(this->fast_.state); } } // secure rng requires no init -> we just passthrough to the global ReadSecureRNG function } void RandomDevice::Read(Memory::MemoryViewWrite view) { if (!view) { SysPushErrorArg(); return; } if (this->def_.bSecure) { ReadSecureRNG(view); } else { WELL_NextBytes(&this->fast_, view.ptr, AuUInt32(view.length)); } } AuString RandomDevice::NextString(AuUInt32 uLength, ERngStringCharacters type) { AuString ret(uLength, '\00'); NextString(ret.data(), AuUInt32(ret.size()), type); return ret; } static double RngConvertToDecimal(AuUInt64 uLargeInt) { AuUInt64 qwValue = (uLargeInt & 0xFFFFFFFFFFFFFull) | 0x3FF0000000000000ull; return *(double *)(&qwValue) - 1.0; } void RandomDevice::NextString(char *pString, AuUInt32 uLength, ERngStringCharacters type) { static AuPair rngSequence[static_cast(ERngStringCharacters::eEnumCount)] = { {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 52}, {"abcdefghijklmnopqrstuvwxyz", 26}, {"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26}, {"1234567890", 10}, {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 62}, {"abcdefghijklmnopqrstuvwxyz1234567890", 36}, {"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 36}, {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890=-+!$%^*.[];:", 75} }; if (!pString) { SysPushErrorArg(); return; } Read(AuMemoryViewWrite { pString, uLength }); if (!ERngStringCharactersIsValid(type)) { SysPushErrorArg("NextString was called with an invalid ERngStringCharacters {}", (AuUInt)type); type = ERngStringCharacters::eAlphaNumericCharacters; // guess we cant just return false } const auto &pair = rngSequence[static_cast(type)]; for (auto i = 0u; i < uLength; i++) { auto uUpperBound = AuRoundUpPow2(pair.second); AuUInt8 uNext {}; auto uWord = reinterpret_cast(pString)[i]; while ((uNext = (uWord & (uUpperBound - 1))) >= pair.second) { uWord = AuFnv1a32Runtime(&uWord, sizeof(uWord)); } pString[i] = pair.first[uNext]; } } AuUInt8 RandomDevice::NextByte() { if (this->def_.bSecure) { AuUInt8 uRet {}; ReadSecureRNG({ &uRet, 1 }); return uRet; } else { return AuUInt8(WELL_NextLong(&this->fast_) & 0xFF); } } bool RandomDevice::NextBoolean() { if (this->def_.bSecure) { AuUInt8 uRet {}; ReadSecureRNG({ &uRet, 1 }); return bool(uRet & 0x1); } else { return bool(WELL_NextLong(&this->fast_) & 0x1); } } AuUInt32 RandomDevice::NextU32() { if (this->def_.bSecure) { AuUInt32 uRet {}; ReadSecureRNG({ &uRet, 4 }); return uRet; } else { return WELL_NextLong(&this->fast_); } } AuUInt64 RandomDevice::NextU64() { if (this->def_.bSecure) { AuUInt64 uRet {}; ReadSecureRNG({ &uRet, 8 }); return uRet; } else { return NextFillTmpl(); } } AuInt32 RandomDevice::NextI32Range(AuInt32 iMin, AuInt32 iMax) { auto uRange = AuUInt32(iMax - iMin); auto uMassiveWord = NextU32(); auto uUpperBound = AuRoundUpPow2(uRange + 1); AuUInt32 uNext {}; while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange) { uMassiveWord = AuFnv1a32Runtime(&uMassiveWord); } return iMin + uNext; } AuUInt32 RandomDevice::NextU32Range(AuUInt32 uMin, AuUInt32 uMax) { auto uRange = uMax - uMin; auto uMassiveWord = NextU32(); auto uUpperBound = AuRoundUpPow2(uRange + 1); AuUInt32 uNext {}; while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange) { uMassiveWord = AuFnv1a32Runtime(&uMassiveWord); } return uMin + uNext; } // Source: https://stackoverflow.com/a/5016867 bool RandomDevice::DecGeometric(int x) { if (x <= 0) { return true; } while (true) { auto r = this->NextByte(); if (x < 8) { return (r & ((1 << x) - 1)) == 0; } else if (r != 0) { return false; } x -= 8; } } // Source: https://stackoverflow.com/a/5016867 double RandomDevice::UniformFloatInRange(double udMin, double udMax) { // No.... #if defined(AURNG_USE_GARBAGE_DECIMALS) return (double(this->NextU32()) * (double(1.0) / double(AuNumericLimits::max()))) * udMax; // No.... #elif defined(AURNG_USE_UNIFORM_DECIMALS) union { double f; AuUInt64 u; } convert; convert.f = udMin; auto uABits = convert.u; convert.f = udMax; auto uBBits = convert.u; auto uMask = uBBits - uABits; uMask |= uMask >> 1; uMask |= uMask >> 2; uMask |= uMask >> 4; uMask |= uMask >> 8; uMask |= uMask >> 16; uMask |= uMask >> 32; int bExp {}; frexp(udMax, &bExp); while (true) { int iXExp {}; double x; auto uXBits = this->NextU64(); uXBits &= uMask; uXBits += uABits; if (uXBits >= uBBits) { continue; } convert.u = uXBits; x = convert.f; frexp(x, &iXExp); if (DecGeometric(bExp - iXExp)) { return x; } } // Yes... #else #if !defined(AURNG_USE_FAST_DECIMALS) #define AURNG_USE_FAST_DECIMALS return 0.0; #endif #endif } AuUInt64 RandomDevice::NextU64Range(AuUInt64 uMin, AuUInt64 uMax) { auto uRange = uMax - uMin; auto uMassiveWord = NextU64(); auto uUpperBound = AuRoundUpPow2(uRange + 1); AuUInt32 uNext {}; while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange) { uMassiveWord = AuFnv1a64Runtime(&uMassiveWord); } return uMin + uNext; } AuInt64 RandomDevice::NextI64Range(AuInt64 iMin, AuInt64 iMax) { auto uRange = AuUInt64(iMax - iMin); auto uMassiveWord = NextU64(); auto uUpperBound = AuRoundUpPow2(uRange + 1); AuUInt32 uNext {}; while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange) { uMassiveWord = AuFnv1a64Runtime(&uMassiveWord); } return iMin + uNext; } AuVec2 RandomDevice::NextVec2(AuVec2 boundA, AuVec2 boundB) { AuVec2 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); return NextVec2Sorted(mins, maxs); } AuVec2 RandomDevice::NextVec2Sorted(AuVec2 min, AuVec2 max) { AuVec2 range; range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; auto uSeed = this->NextU64(); auto dComponentA = RngConvertToDecimal(uSeed); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); return AuVec2 { float((dComponentA * range[0]) + min[0]), float((dComponentB * range[1]) + min[1]) }; } AuVec3 RandomDevice::NextVec3(AuVec3 boundA, AuVec3 boundB) { AuVec3 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); mins[2] = AuMin(boundA[2], boundB[2]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); maxs[2] = AuMax(boundA[2], boundB[2]); return NextVec3Sorted(mins, maxs); } AuVec3 RandomDevice::NextVec3Sorted(AuVec3 min, AuVec3 max) { AuVec3 range; range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; range[2] = max[2] - min[2]; auto uSeed = this->NextU64(); auto dComponentA = RngConvertToDecimal(uSeed); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); return AuVec3 { float((dComponentA * range[0]) + min[0]), float((dComponentB * range[1]) + min[1]), float((dComponentC * range[2]) + min[2]) }; } AuVec4 RandomDevice::NextVec4(AuVec4 boundA, AuVec4 boundB) { AuVec4 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); mins[2] = AuMin(boundA[2], boundB[2]); mins[3] = AuMin(boundA[3], boundB[3]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); maxs[2] = AuMax(boundA[2], boundB[2]); maxs[3] = AuMax(boundA[3], boundB[3]); return NextVec4Sorted(mins, maxs); } AuVec4 RandomDevice::NextVec4Sorted(AuVec4 min, AuVec4 max) { AuVec4 range; range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; range[2] = max[2] - min[2]; range[3] = max[3] - min[3]; auto uSeed = this->NextU64(); auto dComponentA = RngConvertToDecimal(uSeed); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentD = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); return AuVec4 { float((dComponentA * range[0]) + min[0]), float((dComponentB * range[1]) + min[1]), float((dComponentC * range[2]) + min[2]), float((dComponentD * range[3]) + min[3]) }; } AuVecD2 RandomDevice::NextVecD2(AuVecD2 boundA, AuVecD2 boundB) { AuVecD2 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); return NextVecD2Sorted(mins, maxs); } AuVecD2 RandomDevice::NextVecD2Sorted(AuVecD2 min, AuVecD2 max) { AuVecD2 range; range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; auto uSeed = this->NextU64(); auto dComponentA = RngConvertToDecimal(uSeed); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); return AuVecD2 { (dComponentA * range[0]) + min[0], (dComponentB * range[1]) + min[1] }; } AuVecD3 RandomDevice::NextVecD3(AuVecD3 boundA, AuVecD3 boundB) { AuVecD3 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); mins[2] = AuMin(boundA[2], boundB[2]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); maxs[2] = AuMax(boundA[2], boundB[2]); return NextVecD3Sorted(mins, maxs); } AuVecD3 RandomDevice::NextVecD3Sorted(AuVecD3 min, AuVecD3 max) { AuVecD3 range; range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; range[2] = max[2] - min[2]; auto uSeed = this->NextU64(); auto dComponentA = RngConvertToDecimal(uSeed); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); return AuVecD3 { (dComponentA * range[0]) + min[0], (dComponentB * range[1]) + min[1], (dComponentC * range[2]) + min[2] }; } AuVecD4 RandomDevice::NextVecD4(AuVecD4 boundA, AuVecD4 boundB) { AuVecD4 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); mins[2] = AuMin(boundA[2], boundB[2]); mins[3] = AuMin(boundA[3], boundB[3]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); maxs[2] = AuMax(boundA[2], boundB[2]); maxs[3] = AuMax(boundA[3], boundB[3]); return NextVecD4Sorted(mins, maxs); } AuVecD4 RandomDevice::NextVecD4Sorted(AuVecD4 min, AuVecD4 max) { AuVecD4 range; range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; range[2] = max[2] - min[2]; range[3] = max[3] - min[3]; auto uSeed = this->NextU64(); auto dComponentA = RngConvertToDecimal(uSeed); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentD = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); return AuVecD4 { (dComponentA * range[0]) + min[0], (dComponentB * range[1]) + min[1], (dComponentC * range[2]) + min[2], (dComponentD * range[3]) + min[3] }; } double RandomDevice::NextDecimal() { // fast decimals are the default #if defined(AURNG_USE_FAST_DECIMALS) return RngConvertToDecimal(this->NextU64()); #elif defined(AURNG_USE_UNIFORM_DECIMALS) return this->UniformFloatInRange(kDblEpsilon, 1.0 + kDblEpsilon) - kDblEpsilon; #elif defined(AURNG_USE_GARBAGE_DECIMALS) return this->UniformFloatInRange(0, 1.0); #else return 0; #endif } AuUInt32 RandomDevice::NextIndex(AuUInt32 uCount /* = max + 1*/) { auto uMassiveWord = NextU32(); auto uUpperBound = AuRoundUpPow2(uCount); AuUInt32 uNext {}; while ((uNext = (uMassiveWord & (uUpperBound - 1))) >= uCount) { uMassiveWord = AuFnv1a32Runtime(&uMassiveWord); } return uNext; } double RandomDevice::NextNumber(double dMin, double dMax) { auto dRange = dMax - dMin; #if defined(AURNG_USE_FAST_DECIMALS) return (this->NextDecimal() * dRange) + dMin; #else // potentially not deterministic, thanks to runtime/platform deviations return this->UniformFloatInRange(kDblEpsilon, dRange + kDblEpsilon) + dMin - kDblEpsilon; #endif } uuids::uuid RandomDevice::NextUUID() { AuUInt8 bytes[16]; this->Read(bytes); bytes[8] &= 0xBF; bytes[8] |= 0x80; bytes[6] &= 0x4F; bytes[6] |= 0x40; return uuids::uuid { bytes, bytes + 16 }; } AuUInt RandomDevice::NextArrayI32RangeInView(AuMemoryViewWrite write, AuInt32 iMin, AuInt32 iMax) { auto ret = write.Begin(); auto uCount = write.ToCount(); this->Read(write); auto uRange = AuUInt32(iMax - iMin); auto uUpperBound = AuRoundUpPow2(uRange + 1); for (AU_ITERATE_N(uIndex, uCount)) { auto uMassiveWord = write.Begin()[uIndex]; AuUInt32 uNext {}; while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange) { uMassiveWord = AuFnv1a32Runtime(&uMassiveWord); } ret[uIndex] = iMin + uNext; } return uCount; } AuUInt RandomDevice::NextArrayI32RangeFastInView(AuMemoryViewWrite write, AuInt32 iMin, AuInt32 iMax) { auto ret = write.Begin(); auto uCount = write.ToCount(); auto uRange = AuUInt32(iMax - iMin); auto uUpperBound = AuRoundUpPow2(uRange + 1); auto uSeed = this->NextU32(); for (AU_ITERATE_N(uIndex, uCount)) { AuUInt32 uNext {}; uSeed = AuFnv1a32Runtime(&uSeed); while ((uNext = (uSeed & (uUpperBound - 1))) > uRange) { uSeed = AuFnv1a32Runtime(&uSeed); } ret[uIndex] = iMin + uNext; } return uCount; } AuUInt RandomDevice::NextArrayU32RangeInView(AuMemoryViewWrite write, AuUInt32 uMin, AuUInt32 uMax) { auto ret = write.Begin(); auto uCount = write.ToCount(); this->Read(write); auto uRange = uMax - uMin; auto uUpperBound = AuRoundUpPow2(uRange + 1); for (AU_ITERATE_N(uIndex, uCount)) { auto uMassiveWord = ret[uIndex]; AuUInt32 uNext {}; while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange) { uMassiveWord = AuFnv1a32Runtime(&uMassiveWord); } ret[uIndex] = uMin + uNext; } return uCount; } AuUInt RandomDevice::NextArrayU32RangeFastInView(AuMemoryViewWrite write, AuUInt32 uMin, AuUInt32 uMax) { auto ret = write.Begin(); auto uCount = write.ToCount(); auto uRange = uMax - uMin; auto uUpperBound = AuRoundUpPow2(uRange + 1); auto uSeed = this->NextU32(); for (AU_ITERATE_N(uIndex, uCount)) { AuUInt32 uNext {}; uSeed = AuFnv1a32Runtime(&uSeed); while ((uNext = (uSeed & (uUpperBound - 1))) > uRange) { uSeed = AuFnv1a32Runtime(&uSeed); } ret[uIndex] = uMin + uNext; } return uCount; } AuUInt RandomDevice::NextArrayDoubleRangeInView(AuMemoryViewWrite write, double dMin, double dMax) { #if defined(AURNG_USE_FAST_DECIMALS) auto ret = write.Begin(); auto uCount = write.ToCount(); double dRange = dMax - dMin; if constexpr (sizeof(double) == sizeof(AuUInt64)) { this->Read(write); for (AU_ITERATE_N(uIndex, uCount)) { double dValue = RngConvertToDecimal(*(AuUInt64 *)&ret[uIndex]); dValue *= dRange; dValue += dMin; ret[uIndex] = dValue; } } else { RNG_BYTES_PROLOGUE; RNG_BYTES_RESIZE(uCount); this->Read(rngBytes); for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE)) { double dValue = RngConvertToDecimal(rngBytes.Begin()[uIndex]); dValue *= dRange; dValue += dMin; ret[uIndex] = dValue; } } return uCount; #else auto ret = write.Begin(); auto uCount = write.ToCount(); for (AU_ITERATE_N(uIndex, uCount)) { ret[uIndex] = this->NextNumber(dMin, dMax); } return uCount; #endif } AuUInt RandomDevice::NextArrayDoubleRangeFastInView(AuMemoryViewWrite write, double dMin, double dMax) { auto ret = write.Begin(); auto uCount = write.ToCount(); AuUInt64 uSeed = this->NextU64(); double dRange = dMax - dMin; for (AU_ITERATE_N(uIndex, uCount)) { double dValue = RngConvertToDecimal(uSeed); dValue *= dRange; dValue += dMin; ret[uIndex] = dValue; uSeed = AuFnv1a64Runtime<8>(&uSeed); } return uCount; } AuUInt RandomDevice::NextArrayI32InView(AuMemoryViewWrite write) { auto ret = write.Begin(); auto uCount = write.ToCount(); this->Read(write); return uCount; } AuUInt RandomDevice::NextArrayU32InView(AuMemoryViewWrite write) { auto ret = write.Begin(); auto uCount = write.ToCount(); this->Read(write); return uCount; } AuUInt RandomDevice::NextArrayI64RangeFastInView(AuMemoryViewWrite write, AuInt64 iMin, AuInt64 iMax) { auto ret = write.Begin(); auto uCount = write.ToCount(); auto uRange = AuUInt64(iMax - iMin); auto uUpperBound = AuRoundUpPow2(uRange + 1); auto uSeed = this->NextU64(); for (AU_ITERATE_N(uIndex, uCount)) { AuUInt64 uNext {}; uSeed = AuFnv1a64Runtime(&uSeed); while ((uNext = (uSeed & (uUpperBound - 1))) > uRange) { uSeed = AuFnv1a64Runtime(&uSeed); } ret[uIndex] = iMin + uNext; } return uCount; } AuUInt RandomDevice::NextArrayU64RangeFastInView(AuMemoryViewWrite write, AuUInt64 uMin, AuUInt64 uMax) { auto ret = write.Begin(); auto uCount = write.ToCount(); auto uRange = uMax - uMin; auto uUpperBound = AuRoundUpPow2(uRange + 1); auto uSeed = this->NextU64(); for (AU_ITERATE_N(uIndex, uCount)) { AuUInt64 uNext {}; uSeed = AuFnv1a64Runtime(&uSeed); while ((uNext = (uSeed & (uUpperBound - 1))) > uRange) { uSeed = AuFnv1a64Runtime(&uSeed); } ret[uIndex] = uMin + uNext; } return uCount; } AuUInt RandomDevice::NextArrayI64RangeInView(AuMemoryViewWrite write, AuInt64 iMin, AuInt64 iMax) { auto ret = write.Begin(); auto uCount = write.ToCount(); this->Read(write); auto uRange = AuUInt64(iMax - iMin); auto uUpperBound = AuRoundUpPow2(uRange + 1); for (AU_ITERATE_N(uIndex, uCount)) { auto uMassiveWord = write.Begin()[uIndex]; AuUInt64 uNext {}; while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange) { uMassiveWord = AuFnv1a64Runtime(&uMassiveWord); } ret[uIndex] = iMin + uNext; } return uCount; } AuUInt RandomDevice::NextArrayU64RangeInView(AuMemoryViewWrite write, AuUInt64 uMin, AuUInt64 uMax) { auto ret = write.Begin(); auto uCount = write.ToCount(); this->Read(write); auto uRange = uMax - uMin; auto uUpperBound = AuRoundUpPow2(uRange + 1); for (AU_ITERATE_N(uIndex, uCount)) { auto uMassiveWord = ret[uIndex]; AuUInt64 uNext {}; while ((uNext = (uMassiveWord & (uUpperBound - 1))) > uRange) { uMassiveWord = AuFnv1a64Runtime(&uMassiveWord); } ret[uIndex] = uMin + uNext; } return uCount; } AuUInt RandomDevice::NextArrayU32MaskInView(AuMemoryViewWrite write, AuUInt32 uMask) { auto ret = write.Begin(); auto uCount = write.ToCount(); this->Read(write); for (AU_ITERATE_N(i, uCount)) { auto &word = ret[i]; word &= uMask; } return uCount; } AuUInt RandomDevice::NextArrayU64MaskInView(AuMemoryViewWrite write, AuUInt64 uMask) { auto ret = write.Begin(); auto uCount = write.ToCount(); this->Read(write); for (AU_ITERATE_N(i, uCount)) { auto &word = ret[i]; word &= uMask; } return uCount; } AuUInt RandomDevice::NextArrayI64InView(AuMemoryViewWrite write) { auto uCount = write.ToCount(); this->Read(write); return uCount; } AuUInt RandomDevice::NextArrayU64InView(AuMemoryViewWrite write) { auto uCount = write.ToCount(); this->Read(write); return uCount; } AuUInt RandomDevice::NextArrayVec2InView(AuMemoryViewWrite write, AuVec2 boundA, AuVec2 boundB) { AuVec2 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); return NextArrayVec2SortedInView(write, mins, maxs); } AuUInt RandomDevice::NextArrayVec2FastInView(AuMemoryViewWrite write, AuVec2 boundA, AuVec2 boundB) { AuVec2 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); return NextArrayVec2SortedFastInView(write, mins, maxs); } AuUInt RandomDevice::NextArrayVec2SortedInView(AuMemoryViewWrite write, AuVec2 min, AuVec2 max) { AuVec2 range; RNG_BYTES_PROLOGUE; auto ret = write.Begin(); auto uCount = write.ToCount(); RNG_BYTES_RESIZE(uCount); this->Read(rngBytes); range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE)) { auto uSeed = rngBytes.Begin()[uIndex]; auto dComponentA = RngConvertToDecimal(uSeed); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); ret[uIndex] = AuVec2 { float((dComponentA * range[0]) + min[0]), float((dComponentB * range[1]) + min[1]) }; } return uCount; } AuUInt RandomDevice::NextArrayVec2SortedFastInView(AuMemoryViewWrite write, AuVec2 min, AuVec2 max) { AuVec2 range; auto ret = write.Begin(); auto uCount = write.ToCount(); range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; AuUInt64 uSeed = this->NextU64(); for (AU_ITERATE_N(uIndex, uCount)) { auto dComponentA = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); ret[uIndex] = AuVec2 { float((dComponentA * range[0]) + min[0]), float((dComponentB * range[1]) + min[1]) }; } return uCount; } AuUInt RandomDevice::NextArrayVec3InView(AuMemoryViewWrite write, AuVec3 boundA, AuVec3 boundB) { AuVec3 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); mins[2] = AuMin(boundA[2], boundB[2]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); maxs[2] = AuMax(boundA[2], boundB[2]); return NextArrayVec3SortedInView(write, mins, maxs); } AuUInt RandomDevice::NextArrayVec3FastInView(AuMemoryViewWrite write, AuVec3 boundA, AuVec3 boundB) { AuVec3 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); mins[2] = AuMin(boundA[2], boundB[2]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); maxs[2] = AuMax(boundA[2], boundB[2]); return NextArrayVec3SortedFastInView(write, mins, maxs); } AuUInt RandomDevice::NextArrayVec3SortedInView(AuMemoryViewWrite write, AuVec3 min, AuVec3 max) { AuVec3 range; RNG_BYTES_PROLOGUE; auto ret = write.Begin(); auto uCount = write.ToCount(); RNG_BYTES_RESIZE(uCount); this->Read(rngBytes); range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; range[2] = max[2] - min[2]; for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE)) { auto uSeed = rngBytes.Begin()[uIndex]; auto dComponentA = RngConvertToDecimal(uSeed); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); ret[uIndex] = AuVec3 { float((dComponentA * range[0]) + min[0]), float((dComponentB * range[1]) + min[1]), float((dComponentC * range[2]) + min[2]) }; } return uCount; } AuUInt RandomDevice::NextArrayVec3SortedFastInView(AuMemoryViewWrite write, AuVec3 min, AuVec3 max) { AuVec3 range; auto ret = write.Begin(); auto uCount = write.ToCount(); range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; range[2] = max[2] - min[2]; AuUInt64 uSeed = this->NextU64(); for (AU_ITERATE_N(uIndex, uCount)) { auto dComponentA = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); ret[uIndex] = AuVec3 { float((dComponentA * range[0]) + min[0]), float((dComponentB * range[1]) + min[1]), float((dComponentC * range[2]) + min[2]) }; } return uCount; } AuUInt RandomDevice::NextArrayVec4InView(AuMemoryViewWrite write, AuVec4 boundA, AuVec4 boundB) { AuVec4 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); mins[2] = AuMin(boundA[2], boundB[2]); mins[3] = AuMin(boundA[3], boundB[3]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); maxs[2] = AuMax(boundA[2], boundB[2]); maxs[3] = AuMax(boundA[3], boundB[3]); return NextArrayVec4SortedInView(write, mins, maxs); } AuUInt RandomDevice::NextArrayVec4FastInView(AuMemoryViewWrite write, AuVec4 boundA, AuVec4 boundB) { AuVec4 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); mins[2] = AuMin(boundA[2], boundB[2]); mins[3] = AuMin(boundA[3], boundB[3]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); maxs[2] = AuMax(boundA[2], boundB[2]); maxs[3] = AuMax(boundA[3], boundB[3]); return NextArrayVec4SortedFastInView(write, mins, maxs); } AuUInt RandomDevice::NextArrayVec4SortedInView(AuMemoryViewWrite write, AuVec4 min, AuVec4 max) { AuVec4 range; RNG_BYTES_PROLOGUE; auto ret = write.Begin(); auto uCount = write.ToCount(); RNG_BYTES_RESIZE(uCount); this->Read(rngBytes); range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; range[2] = max[2] - min[2]; range[3] = max[3] - min[3]; for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE)) { auto uSeed = rngBytes.Begin()[uIndex]; auto dComponentA = RngConvertToDecimal(uSeed); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentD = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); ret[uIndex] = AuVec4 { float((dComponentA * range[0]) + min[0]), float((dComponentB * range[1]) + min[1]), float((dComponentC * range[2]) + min[2]), float((dComponentD * range[3]) + min[3]) }; } return uCount; } AuUInt RandomDevice::NextArrayVec4SortedFastInView(AuMemoryViewWrite write, AuVec4 min, AuVec4 max) { AuVec4 range; auto ret = write.Begin(); auto uCount = write.ToCount(); range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; range[2] = max[2] - min[2]; range[3] = max[3] - min[3]; AuUInt64 uSeed = this->NextU64(); for (AU_ITERATE_N(uIndex, uCount)) { auto dComponentA = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentD = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); ret[uIndex] = AuVec4 { float((dComponentA * range[0]) + min[0]), float((dComponentB * range[1]) + min[1]), float((dComponentC * range[2]) + min[2]), float((dComponentD * range[3]) + min[3]) }; } return uCount; } AuUInt RandomDevice::NextArrayVecD2InView(AuMemoryViewWrite write, AuVecD2 boundA, AuVecD2 boundB) { AuVecD2 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); return NextArrayVecD2SortedInView(write, mins, maxs); } AuUInt RandomDevice::NextArrayVecD2FastInView(AuMemoryViewWrite write, AuVecD2 boundA, AuVecD2 boundB) { AuVecD2 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); return NextArrayVecD2SortedFastInView(write, mins, maxs); } AuUInt RandomDevice::NextArrayVecD2SortedInView(AuMemoryViewWrite write, AuVecD2 min, AuVecD2 max) { AuVecD2 range; RNG_BYTES_PROLOGUE; auto ret = write.Begin(); auto uCount = write.ToCount(); RNG_BYTES_RESIZE(uCount); this->Read(rngBytes); range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE)) { auto uSeed = rngBytes.Begin()[uIndex]; auto dComponentA = RngConvertToDecimal(uSeed); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); ret[uIndex] = AuVecD2 { (dComponentA * range[0]) + min[0], (dComponentB * range[1]) + min[1] }; } return uCount; } AuUInt RandomDevice::NextArrayVecD2SortedFastInView(AuMemoryViewWrite write, AuVecD2 min, AuVecD2 max) { AuVecD2 range; auto ret = write.Begin(); auto uCount = write.ToCount(); range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; AuUInt64 uSeed = this->NextU64(); for (AU_ITERATE_N(uIndex, uCount)) { auto dComponentA = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); ret[uIndex] = AuVecD2 { (dComponentA * range[0]) + min[0], (dComponentB * range[1]) + min[1] }; } return uCount; } AuUInt RandomDevice::NextArrayVecD3InView(AuMemoryViewWrite write, AuVecD3 boundA, AuVecD3 boundB) { AuVecD3 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); mins[2] = AuMin(boundA[2], boundB[2]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); maxs[2] = AuMax(boundA[2], boundB[2]); return NextArrayVecD3SortedInView(write, mins, maxs); } AuUInt RandomDevice::NextArrayVecD3FastInView(AuMemoryViewWrite write, AuVecD3 boundA, AuVecD3 boundB) { AuVecD3 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); mins[2] = AuMin(boundA[2], boundB[2]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); maxs[2] = AuMax(boundA[2], boundB[2]); return NextArrayVecD3SortedFastInView(write, mins, maxs); } AuUInt RandomDevice::NextArrayVecD3SortedInView(AuMemoryViewWrite write, AuVecD3 min, AuVecD3 max) { AuVecD3 range; RNG_BYTES_PROLOGUE; auto ret = write.Begin(); auto uCount = write.ToCount(); RNG_BYTES_RESIZE(uCount); this->Read(rngBytes); range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; range[2] = max[2] - min[2]; for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE)) { auto uSeed = rngBytes.Begin()[uIndex]; auto dComponentA = RngConvertToDecimal(uSeed); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); ret[uIndex] = AuVecD3 { (dComponentA * range[0]) + min[0], (dComponentB * range[1]) + min[1], (dComponentC * range[2]) + min[2] }; } return uCount; } AuUInt RandomDevice::NextArrayVecD3SortedFastInView(AuMemoryViewWrite write, AuVecD3 min, AuVecD3 max) { AuVecD3 range; auto ret = write.Begin(); auto uCount = write.ToCount(); range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; range[2] = max[2] - min[2]; AuUInt64 uSeed = this->NextU64(); for (AU_ITERATE_N(uIndex, uCount)) { auto dComponentA = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); ret[uIndex] = AuVecD3 { (dComponentA * range[0]) + min[0], (dComponentB * range[1]) + min[1], (dComponentC * range[2]) + min[2] }; } return uCount; } AuUInt RandomDevice::NextArrayVecD4InView(AuMemoryViewWrite write, AuVecD4 boundA, AuVecD4 boundB) { AuVecD4 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); mins[2] = AuMin(boundA[2], boundB[2]); mins[3] = AuMin(boundA[3], boundB[3]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); maxs[2] = AuMax(boundA[2], boundB[2]); maxs[3] = AuMax(boundA[3], boundB[3]); return NextArrayVecD4SortedInView(write, mins, maxs); } AuUInt RandomDevice::NextArrayVecD4FastInView(AuMemoryViewWrite write, AuVecD4 boundA, AuVecD4 boundB) { AuVecD4 mins, maxs; mins[0] = AuMin(boundA[0], boundB[0]); mins[1] = AuMin(boundA[1], boundB[1]); mins[2] = AuMin(boundA[2], boundB[2]); mins[3] = AuMin(boundA[3], boundB[3]); maxs[0] = AuMax(boundA[0], boundB[0]); maxs[1] = AuMax(boundA[1], boundB[1]); maxs[2] = AuMax(boundA[2], boundB[2]); maxs[3] = AuMax(boundA[3], boundB[3]); return NextArrayVecD4SortedFastInView(write, mins, maxs); } AuUInt RandomDevice::NextArrayVecD4SortedInView(AuMemoryViewWrite write, AuVecD4 min, AuVecD4 max) { AuVecD4 range; RNG_BYTES_PROLOGUE; auto ret = write.Begin(); auto uCount = write.ToCount(); RNG_BYTES_RESIZE(uCount); this->Read(rngBytes); range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; range[2] = max[2] - min[2]; range[3] = max[3] - min[3]; for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE)) { auto uSeed = rngBytes.Begin()[uIndex]; auto dComponentA = RngConvertToDecimal(uSeed); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentD = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); ret[uIndex] = AuVecD4 { (dComponentA * range[0]) + min[0], (dComponentB * range[1]) + min[1], (dComponentC * range[2]) + min[2], (dComponentD * range[3]) + min[3] }; } return uCount; } AuUInt RandomDevice::NextArrayVecD4SortedFastInView(AuMemoryViewWrite write, AuVecD4 min, AuVecD4 max) { AuVecD4 range; auto ret = write.Begin(); auto uCount = write.ToCount(); range[0] = max[0] - min[0]; range[1] = max[1] - min[1]; range[2] = max[2] - min[2]; range[3] = max[3] - min[3]; AuUInt64 uSeed = this->NextU64(); for (AU_ITERATE_N(uIndex, uCount)) { auto dComponentA = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentB = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentC = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); auto dComponentD = RngConvertToDecimal(uSeed = (AuFnv1a64Runtime<8>(&uSeed))); ret[uIndex] = AuVecD4 { (dComponentA * range[0]) + min[0], (dComponentB * range[1]) + min[1], (dComponentC * range[2]) + min[2], (dComponentD * range[3]) + min[3] }; } return uCount; } AuUInt RandomDevice::NextArrayDoubleInView(AuMemoryViewWrite write) { auto ret = write.Begin(); auto uCount = write.ToCount(); this->Read(write); return uCount; } AuUInt RandomDevice::NextArrayDecimalsInView(AuMemoryViewWrite write) { #if defined(AURNG_USE_FAST_DECIMALS) auto ret = write.Begin(); auto uCount = write.ToCount(); if constexpr (sizeof(double) == sizeof(AuUInt64)) { this->Read(write); for (AU_ITERATE_N(uIndex, uCount)) { ret[uIndex] = RngConvertToDecimal(*(AuUInt64*)&ret[uIndex]); } } else { RNG_BYTES_PROLOGUE; RNG_BYTES_RESIZE(uCount); this->Read(rngBytes); for (AU_ITERATE_N(uIndex, RNG_BYTES_SIZE)) { ret[uIndex] = RngConvertToDecimal(rngBytes.Begin()[uIndex]); } } return uCount; #else auto ret = write.Begin(); auto uCount = write.ToCount(); for (AU_ITERATE_N(uIndex, uCount)) { ret[uIndex] = this->NextDecimal(); } return uCount; #endif } AuUInt RandomDevice::NextArrayDecimalsFastInView(AuMemoryViewWrite write) { auto ret = write.Begin(); auto uCount = write.ToCount(); AuUInt64 uSeed = this->NextU64(); for (AU_ITERATE_N(uIndex, uCount)) { ret[uIndex] = RngConvertToDecimal(uSeed); uSeed = AuFnv1a64Runtime<8>(&uSeed); } return uCount; } AuUInt RandomDevice::NextArrayUUIDsInView(AuMemoryViewWrite write) { auto ret = write.Begin(); auto uCount = write.ToCount(); if constexpr (sizeof(uuids::uuid) == 16) { this->Read(write); for (AU_ITERATE_N(uIndex, uCount)) { auto pBytes = write.Begin() + (uIndex * 16); pBytes[8] &= 0xBF; pBytes[8] |= 0x80; pBytes[6] &= 0x4F; pBytes[6] |= 0x40; } } else { AuList rngBytes; rngBytes.resize(uCount * 16); this->Read(rngBytes); for (AU_ITERATE_N(uIndex, uCount)) { auto pBytes = rngBytes.data() + (uIndex * 16); pBytes[8] &= 0xBF; pBytes[8] |= 0x80; pBytes[6] &= 0x4F; pBytes[6] |= 0x40; ret[uIndex] = uuids::uuid { pBytes, pBytes + 16 }; } } return uCount; } AuList RandomDevice::NextArrayI32Range(AuUInt32 uCount, AuInt32 iMin, AuInt32 iMax) { AuList ret; ret.resize(uCount); (void)NextArrayI32RangeInView(ret, iMin, iMax); return ret; } AuList RandomDevice::NextArrayI32RangeFast(AuUInt32 uCount, AuInt32 iMin, AuInt32 iMax) { AuList ret; ret.resize(uCount); (void)NextArrayI32RangeFastInView(ret, iMin, iMax); return ret; } AuList RandomDevice::NextArrayU32Range(AuUInt32 uCount, AuUInt32 uMin, AuUInt32 uMax) { AuList ret; ret.resize(uCount); (void)NextArrayU32RangeInView(ret, uMin, uMax); return ret; } AuList RandomDevice::NextArrayU32RangeFast(AuUInt32 uCount, AuUInt32 uMin, AuUInt32 uMax) { AuList ret; ret.resize(uCount); (void)NextArrayU32RangeFastInView(ret, uMin, uMax); return ret; } AuList RandomDevice::NextArrayDoubleRange(AuUInt32 uCount, double dMin, double dMax) { AuList ret; ret.resize(uCount); (void)NextArrayDoubleRangeInView(ret, dMin, dMax); return ret; } AuList RandomDevice::NextArrayDoubleRangeFast(AuUInt32 uCount, double dMin, double dMax) { AuList ret; ret.resize(uCount); (void)NextArrayDoubleRangeFastInView(ret, dMin, dMax); return ret; } AuList RandomDevice::NextArrayI32(AuUInt32 uCount) { AuList ret; ret.resize(uCount); (void)NextArrayI32InView(ret); return ret; } AuList RandomDevice::NextArrayU32(AuUInt32 uCount) { AuList ret; ret.resize(uCount); (void)NextArrayU32InView(ret); return ret; } AuList RandomDevice::NextArrayI64RangeFast(AuUInt32 uCount, AuInt64 iMin, AuInt64 iMax) { AuList ret; ret.resize(uCount); (void)NextArrayI64RangeFastInView(ret, iMin, iMax); return ret; } AuList RandomDevice::NextArrayU64RangeFast(AuUInt32 uCount, AuUInt64 uMin, AuUInt64 uMax) { AuList ret; ret.resize(uCount); (void)NextArrayU64RangeFastInView(ret, uMin, uMax); return ret; } AuList RandomDevice::NextArrayI64Range(AuUInt32 uCount, AuInt64 iMin, AuInt64 iMax) { AuList ret; ret.resize(uCount); (void)NextArrayI64RangeInView(ret, iMin, iMax); return ret; } AuList RandomDevice::NextArrayU64Range(AuUInt32 uCount, AuUInt64 uMin, AuUInt64 uMax) { AuList ret; ret.resize(uCount); (void)NextArrayU64RangeInView(ret, uMin, uMax); return ret; } AuList RandomDevice::NextArrayU32Mask(AuUInt32 uCount, AuUInt32 uMask) { AuList ret; ret.resize(uCount); (void)NextArrayU32MaskInView(ret, uMask); return ret; } AuList RandomDevice::NextArrayU64Mask(AuUInt32 uCount, AuUInt64 uMask) { AuList ret; ret.resize(uCount); (void)NextArrayU64MaskInView(ret, uMask); return ret; } AuList RandomDevice::NextArrayI64(AuUInt32 uCount) { AuList ret; ret.resize(uCount); (void)NextArrayI64InView(ret); return ret; } AuList RandomDevice::NextArrayU64(AuUInt32 uCount) { AuList ret; ret.resize(uCount); (void)NextArrayU64InView(ret); return ret; } AuList RandomDevice::NextArrayVec2(AuUInt32 uCount, AuVec2 boundA, AuVec2 boundB) { AuList ret; ret.resize(uCount); (void)NextArrayVec2InView(ret, boundA, boundB); return ret; } AuList RandomDevice::NextArrayVec2Fast(AuUInt32 uCount, AuVec2 boundA, AuVec2 boundB) { AuList ret; ret.resize(uCount); (void)NextArrayVec2FastInView(ret, boundA, boundB); return ret; } AuList RandomDevice::NextArrayVec2Sorted(AuUInt32 uCount, AuVec2 min, AuVec2 max) { AuList ret; ret.resize(uCount); (void)NextArrayVec2SortedInView(ret, min, max); return ret; } AuList RandomDevice::NextArrayVec2SortedFast(AuUInt32 uCount, AuVec2 min, AuVec2 max) { AuList ret; ret.resize(uCount); (void)NextArrayVec2SortedFastInView(ret, min, max); return ret; } AuList RandomDevice::NextArrayVec3(AuUInt32 uCount, AuVec3 boundA, AuVec3 boundB) { AuList ret; ret.resize(uCount); (void)NextArrayVec3InView(ret, boundA, boundB); return ret; } AuList RandomDevice::NextArrayVec3Fast(AuUInt32 uCount, AuVec3 boundA, AuVec3 boundB) { AuList ret; ret.resize(uCount); (void)NextArrayVec3FastInView(ret, boundA, boundB); return ret; } AuList RandomDevice::NextArrayVec3Sorted(AuUInt32 uCount, AuVec3 min, AuVec3 max) { AuList ret; ret.resize(uCount); (void)NextArrayVec3SortedInView(ret, min, max); return ret; } AuList RandomDevice::NextArrayVec3SortedFast(AuUInt32 uCount, AuVec3 min, AuVec3 max) { AuList ret; ret.resize(uCount); (void)NextArrayVec3SortedFastInView(ret, min, max); return ret; } AuList RandomDevice::NextArrayVec4(AuUInt32 uCount, AuVec4 boundA, AuVec4 boundB) { AuList ret; ret.resize(uCount); (void)NextArrayVec4InView(ret, boundA, boundB); return ret; } AuList RandomDevice::NextArrayVec4Fast(AuUInt32 uCount, AuVec4 boundA, AuVec4 boundB) { AuList ret; ret.resize(uCount); (void)NextArrayVec4FastInView(ret, boundA, boundB); return ret; } AuList RandomDevice::NextArrayVec4Sorted(AuUInt32 uCount, AuVec4 min, AuVec4 max) { AuList ret; ret.resize(uCount); (void)NextArrayVec4SortedInView(ret, min, max); return ret; } AuList RandomDevice::NextArrayVec4SortedFast(AuUInt32 uCount, AuVec4 min, AuVec4 max) { AuList ret; ret.resize(uCount); (void)NextArrayVec4SortedFastInView(ret, min, max); return ret; } AuList RandomDevice::NextArrayVecD2(AuUInt32 uCount, AuVecD2 boundA, AuVecD2 boundB) { AuList ret; ret.resize(uCount); (void)NextArrayVecD2InView(ret, boundA, boundB); return ret; } AuList RandomDevice::NextArrayVecD2Fast(AuUInt32 uCount, AuVecD2 boundA, AuVecD2 boundB) { AuList ret; ret.resize(uCount); (void)NextArrayVecD2FastInView(ret, boundA, boundB); return ret; } AuList RandomDevice::NextArrayVecD2Sorted(AuUInt32 uCount, AuVecD2 min, AuVecD2 max) { AuList ret; ret.resize(uCount); (void)NextArrayVecD2SortedInView(ret, min, max); return ret; } AuList RandomDevice::NextArrayVecD2SortedFast(AuUInt32 uCount, AuVecD2 min, AuVecD2 max) { AuList ret; ret.resize(uCount); (void)NextArrayVecD2SortedFastInView(ret, min, max); return ret; } AuList RandomDevice::NextArrayVecD3(AuUInt32 uCount, AuVecD3 boundA, AuVecD3 boundB) { AuList ret; ret.resize(uCount); (void)NextArrayVecD3InView(ret, boundA, boundB); return ret; } AuList RandomDevice::NextArrayVecD3Fast(AuUInt32 uCount, AuVecD3 boundA, AuVecD3 boundB) { AuList ret; ret.resize(uCount); (void)NextArrayVecD3FastInView(ret, boundA, boundB); return ret; } AuList RandomDevice::NextArrayVecD3Sorted(AuUInt32 uCount, AuVecD3 min, AuVecD3 max) { AuList ret; ret.resize(uCount); (void)NextArrayVecD3SortedInView(ret, min, max); return ret; } AuList RandomDevice::NextArrayVecD3SortedFast(AuUInt32 uCount, AuVecD3 min, AuVecD3 max) { AuList ret; ret.resize(uCount); (void)NextArrayVecD3SortedFastInView(ret, min, max); return ret; } AuList RandomDevice::NextArrayVecD4(AuUInt32 uCount, AuVecD4 boundA, AuVecD4 boundB) { AuList ret; ret.resize(uCount); (void)NextArrayVecD4InView(ret, boundA, boundB); return ret; } AuList RandomDevice::NextArrayVecD4Fast(AuUInt32 uCount, AuVecD4 boundA, AuVecD4 boundB) { AuList ret; ret.resize(uCount); (void)NextArrayVecD4FastInView(ret, boundA, boundB); return ret; } AuList RandomDevice::NextArrayVecD4Sorted(AuUInt32 uCount, AuVecD4 min, AuVecD4 max) { AuList ret; ret.resize(uCount); (void)NextArrayVecD4SortedInView(ret, min, max); return ret; } AuList RandomDevice::NextArrayVecD4SortedFast(AuUInt32 uCount, AuVecD4 min, AuVecD4 max) { AuList ret; ret.resize(uCount); (void)NextArrayVecD4SortedFastInView(ret, min, max); return ret; } AuList RandomDevice::NextArrayDouble(AuUInt32 uCount) { AuList ret; ret.resize(uCount); (void)NextArrayDoubleInView(ret); return ret; } AuList RandomDevice::NextArrayDecimals(AuUInt32 uCount) { AuList ret; ret.resize(uCount); (void)NextArrayDecimalsInView(ret); return ret; } AuList RandomDevice::NextArrayDecimalsFast(AuUInt32 uCount) { AuList ret; ret.resize(uCount); (void)NextArrayDecimalsFastInView(ret); return ret; } AuList RandomDevice::NextArrayUUIDs(AuUInt32 uCount) { AuList ret; ret.resize(uCount); (void)NextArrayUUIDsInView(ret); return ret; } AuMemoryViewRead RandomDevice::ToSeed() { if (this->def_.bSecure) { return {}; } return this->fast_.state; } IO::IStreamReader *RandomDevice::ToStreamReader() { return this; } AUKN_SYM IRandomDevice *RandomNew(const Aurora::RNG::RandomDef &def) { auto pDevice = _new RandomDevice(); if (!pDevice) { return nullptr; } pDevice->Init(def); return pDevice; } AUKN_SYM void RandomRelease(IRandomDevice *pDevice) { AuSafeDelete(pDevice); } AUROXTL_INTERFACE_SOO_SRC(Random, RandomDevice, (const RandomDef &, def)) }