Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 09:34:28

0001 #pragma once
0002 
0003 #include <cstdint>
0004 #include <functional>
0005 #include <vector>
0006 
0007 namespace algorithms::detail {
0008 
0009 // Auto-refreshing cached sequence from an underlying random engine allowing for multiple instances
0010 // to be evaluated in parallel. Specs:
0011 //   - GenFunc is required to return N random numbers between 0 and
0012 //     std::numeric_limits<uint_fast64_t>::max()
0013 //   - GenFunc is responsible to deal with possible simultaneous access by multiple
0014 //     instances of CachedBitGenerator (required to be thread-safe).
0015 //   - The owner of a CachedGenerator instance is responsible to prevent parallel
0016 //     calls to ::operator()
0017 //  Implements the uniform_random_bit_generator concept
0018 class CachedBitGenerator {
0019 public:
0020   using result_type = uint_fast64_t;
0021   using GenFunc    = std::function<std::vector<result_type>(size_t /* N */)>;
0022   CachedBitGenerator(const GenFunc& gen, const size_t cache_size)
0023       // index starts at the end of the (empty) cache to force an immediate refresh
0024       // on first access
0025       : m_gen{gen}, m_cache(cache_size), m_index{cache_size} {}
0026 
0027   result_type operator()() {
0028     if (m_index >= m_cache.size()) {
0029       refresh();
0030     }
0031     return m_cache[m_index++];
0032   }
0033 
0034   static constexpr result_type min() { return 0; }
0035   static constexpr result_type max() { return std::numeric_limits<result_type>::max(); }
0036 
0037 private:
0038   void refresh() {
0039     m_cache = m_gen(m_cache.size());
0040     m_index = 0;
0041   }
0042 
0043   GenFunc m_gen;
0044   std::vector<CachedBitGenerator::result_type> m_cache;
0045   size_t m_index;
0046 };
0047 
0048 } // namespace algorithms::detail