Changeset 1a617ac in mainline
- Timestamp:
- 2018-07-05T21:41:22Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2fe861d
- Parents:
- 4654b29
- git-author:
- Dzejrou <dzejrou@…> (2018-05-02 15:43:15)
- git-committer:
- Dzejrou <dzejrou@…> (2018-07-05 21:41:22)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/cpp/include/impl/random.hpp
r4654b29 r1a617ac 33 33 #include <ctime> 34 34 #include <initializer_list> 35 #include <internal/builtins.hpp> 35 36 #include <limits> 36 37 #include <type_traits> … … 43 44 * they should seek the mentioned standard section near 44 45 * the declaration of these variables. 46 * Note: There will be a lot of mathematical expressions in this header. 47 * All of these are taken directly from the standard's requirements 48 * and as such won't be commented here, check the appropriate 49 * sections if you need explanation of these forumulae. 45 50 */ 46 51 … … 75 80 class linear_congruential_engine 76 81 { 82 static_assert(m == 0 || (a < m && c < m)); 83 77 84 public: 78 85 using result_type = UIntType; … … 94 101 static constexpr result_type default_seed = 1U; 95 102 96 explicit linear_congruential_engine(result_type s = default_seed); 103 explicit linear_congruential_engine(result_type s = default_seed) 104 : state_{} 105 { 106 seed(s); 107 } 108 109 linear_congruential_engine(const linear_congruential_engine& other) 110 : state_{other.state_} 111 { /* DUMMY BODY */ } 97 112 98 113 template<class Seq> 99 114 explicit linear_congruential_engine( 100 115 enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q 101 ); 102 103 void seed(result_type s = default_seed); 116 ) 117 : state_{} 118 { 119 size_t k = static_cast<size_t>(aux::ceil(aux::log2(modulus_) / 32)); 120 auto arr = new result_type[k + 3]; 121 122 q.generate(arr, arr + k + 3); 123 124 result_type s{}; 125 for (size_t j = 0; j < k; ++j) 126 s += a[j + 3] * aux::pow2(32U * j); 127 s = s % modulus_; 128 129 seed(s); 130 } 131 132 void seed(result_type s = default_seed) 133 { 134 if (c % modulus_ == 0 && s == 0) 135 state_ = 0; 136 else 137 state_ = s; 138 } 104 139 105 140 template<class Seq> … … 108 143 ); 109 144 110 result_type operator()(); 111 112 void discard(unsigned long long z); 145 result_type operator()() 146 { 147 return generate_(); 148 } 149 150 void discard(unsigned long long z) 151 { 152 for (unsigned long long i = 0ULL; i < z; ++i) 153 transition_(); 154 } 155 156 bool operator==(const linear_congruential_engine& rhs) const 157 { 158 return state_ = rhs.state_; 159 } 160 161 bool operator!=(const linear_congruential_engine& rhs) const 162 { 163 return !(*this == rhs); 164 } 165 166 template<class Char, class Traits> 167 basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const 168 { 169 auto flags = os.flags(); 170 os.flags(ios_base::dec | ios_base::left); 171 172 os << state_; 173 174 os.flags(flags); 175 return os; 176 } 177 178 template<class Char, class Traits> 179 basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const 180 { 181 auto flags = is.flags(); 182 is.flags(ios_base::dec); 183 184 result_type tmp{}; 185 if (is >> tmp) 186 state_ = tmp; 187 else 188 is.setstate(ios::failbit); 189 190 is.flags(flags); 191 return is; 192 } 193 194 private: 195 result_type state_; 196 197 static constexpr result_type modulus_ = 198 (m == 0) ? (numeric_limits<result_type>::max() + 1) : m; 199 200 void transition_() 201 { 202 state_ = (a * state_ + c) % modulus_; 203 } 204 205 result_type generate_() 206 { 207 transition_(); 208 209 return state_; 210 } 113 211 }; 114 212
Note:
See TracChangeset
for help on using the changeset viewer.