Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 #ifndef __MicroURNG_dot_hpp__
00033 #define __MicroURNG_dot_hpp__
00034 
00035 #include <stdexcept>
00036 #include <limits>
00037 
00038 namespace r123{
00078 template<typename CBRNG>
00079 class MicroURNG{
00080     
00081     
00082     
00083     
00084     
00085 public:
00086     typedef CBRNG cbrng_type;
00087     static const int BITS = 32;
00088     typedef typename cbrng_type::ctr_type ctr_type;
00089     typedef typename cbrng_type::key_type key_type;
00090     typedef typename cbrng_type::ukey_type ukey_type;
00091     typedef typename ctr_type::value_type result_type;
00092 
00093     R123_STATIC_ASSERT( std::numeric_limits<result_type>::digits >= BITS, "The result_type must have at least 32 bits" );
00094 
00095     result_type operator()(){
00096         if(last_elem == 0){
00097             
00098             const size_t W = std::numeric_limits<result_type>::digits;
00099             ctr_type c = c0;
00100             c[c0.size()-1] |= n<<(W-BITS);
00101             rdata = b(c,k);
00102             n++;
00103             last_elem = rdata.size();
00104         }
00105         return rdata[--last_elem];
00106     }
00107     MicroURNG(cbrng_type _b, ctr_type _c0, ukey_type _uk) : b(_b), c0(_c0), k(_uk), n(0), last_elem(0) {
00108         chkhighbits();
00109     }
00110     MicroURNG(ctr_type _c0, ukey_type _uk) : b(), c0(_c0), k(_uk), n(0), last_elem(0) {
00111         chkhighbits();
00112     }
00113 
00114     
00115     
00116     const static result_type _Min = 0;
00117     const static result_type _Max = ~((result_type)0);
00118 
00119     static R123_CONSTEXPR result_type min R123_NO_MACRO_SUBST () { return _Min; }
00120     static R123_CONSTEXPR result_type max R123_NO_MACRO_SUBST () { return _Max; }
00121     
00122     const ctr_type& counter() const{ return c0; }
00123     void reset(ctr_type _c0, ukey_type _uk){
00124         c0 = _c0;
00125         chkhighbits();
00126         k = _uk;
00127         n = 0;
00128         last_elem = 0;
00129     }
00130 
00131 private:
00132     cbrng_type b;
00133     ctr_type c0;
00134     key_type k;
00135     R123_ULONG_LONG n;
00136     size_t last_elem;
00137     ctr_type rdata;
00138     void chkhighbits(){
00139         result_type r = c0[c0.size()-1];
00140         result_type mask = ((uint64_t)std::numeric_limits<result_type>::max R123_NO_MACRO_SUBST ())>>BITS;
00141         if((r&mask) != r)
00142             throw std::runtime_error("MicroURNG: c0, does not have high bits clear");
00143     }
00144 };
00145 } 
00146 #endif