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{
00080 template<typename CBRNG, unsigned int _BITS>
00081 class MicroURNG{
00082     
00083     
00084     
00085     
00086     
00087 public:
00088     typedef CBRNG cbrng_type;
00089     static const unsigned BITS = _BITS;
00090     typedef typename cbrng_type::ctr_type ctr_type;
00091     typedef typename cbrng_type::key_type key_type;
00092     typedef typename ctr_type::value_type result_type;
00093 
00094     result_type operator()(){
00095         if(last_elem == 0){
00096             
00097             if( n >= (((R123_ULONG_LONG)1)<<BITS) )
00098                 throw std::runtime_error("Incremented high bits of MicroURNG's counter too many times");
00099             const size_t W = std::numeric_limits<result_type>::digits;
00100             ctr_type c = c0;
00101             c[c0.size()-1] |= n<<(W-BITS);
00102             rdata = b(c,k);
00103             n++;
00104             last_elem = rdata.size();
00105         }
00106         return rdata[--last_elem];
00107     }
00108     MicroURNG(cbrng_type _b, ctr_type _c0, key_type _k) : b(_b), c0(_c0), k(_k), n(0), last_elem(0) {
00109         chkhighbits();
00110     }
00111     MicroURNG(ctr_type _c0, key_type _k) : b(), c0(_c0), k(_k), n(0), last_elem(0) {
00112         chkhighbits();
00113     }
00114     result_type min() const{
00115         return std::numeric_limits<result_type>::min();
00116     }
00117     result_type max() const{
00118         return std::numeric_limits<result_type>::max();
00119     }
00120     
00121     const ctr_type& counter() const{ return c0; }
00122     const key_type& key() const{ return k; }
00123     void reset(ctr_type _c0, key_type _k){
00124         c0 = _c0;
00125         chkhighbits();
00126         k = _k;
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 = std::numeric_limits<result_type>::max()>>BITS;
00141         if((r&mask) != r)
00142             throw std::runtime_error("MicroURNG: c0, does not have high bits clear");
00143     }
00144 };
00145 } 
00146 #endif