diff --git a/CMakeLists.txt b/CMakeLists.txt index fa07543..b042b02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ add_library( alepha SHARED Console.cc ProgramOptions.cc string_algorithms.cc + fastRandom.cc word_wrap.cc Thread.cc delimited_list.cc diff --git a/fastRandom.cc b/fastRandom.cc new file mode 100644 index 0000000..8e01c24 --- /dev/null +++ b/fastRandom.cc @@ -0,0 +1,63 @@ +static_assert( __cplusplus > 2023'00 ); + +#include "fastRandom.h" + +#include + +#include + +namespace Alepha::Hydrogen ::detail:: fastRandom_m +{ + namespace + { + struct FastRandomState + { + boost::random::taus88 fastRandomState{ std::random_device{}() }; + std::uint32_t pool; + int remainingBits= 0; + + void + next() + { + pool= fastRandomState(); + remainingBits= 32; + } + + void + refresh() + { + if( remainingBits == 0 ) next(); + } + + std::uint32_t + getBit() + { + refresh(); + const std::uint32_t rv= pool & 1; + --remainingBits; + pool>>= 1; + return rv; + } + + std::uint32_t + get( int count ) + { + std::uint32_t rv= 0; + while( count-- ) + { + rv<<= 1; + rv|= getBit(); + } + return rv; + } + }; + + thread_local FastRandomState fastRandom; + } + + std::uint32_t + exports::fastRandomBits( const int numBits ) + { + return fastRandom.get( numBits ); + } +} diff --git a/fastRandom.h b/fastRandom.h new file mode 100644 index 0000000..3febd23 --- /dev/null +++ b/fastRandom.h @@ -0,0 +1,20 @@ +static_assert( __cplusplus > 2023'00 ); + +#pragma once + +#include + +#include + +namespace Alepha::Hydrogen ::detail:: fastRandom_m +{ + inline namespace exports + { + std::uint32_t fastRandomBits( int numBits ); + } +} + +namespace Alepha::Hydrogen::inline exports::inline fastRandom_m +{ + using namespace detail::fastRandom_m::exports; +}