diff --git a/include/boost/random/lagged_fibonacci.hpp b/include/boost/random/lagged_fibonacci.hpp index 9e184d00e..3b8da0375 100644 --- a/include/boost/random/lagged_fibonacci.hpp +++ b/include/boost/random/lagged_fibonacci.hpp @@ -153,9 +153,9 @@ class lagged_fibonacci_engine */ BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lagged_fibonacci_engine, f) { - is >> f.i >> std::ws; + is >> f.i; for(unsigned int j = 0; j < f.long_lag; ++j) - is >> f.x[j] >> std::ws; + is >> std::ws >> f.x[j]; return is; } diff --git a/include/boost/random/mersenne_twister.hpp b/include/boost/random/mersenne_twister.hpp index 6665e208d..b51eb83af 100644 --- a/include/boost/random/mersenne_twister.hpp +++ b/include/boost/random/mersenne_twister.hpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -216,26 +217,28 @@ class mersenne_twister_engine #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS /** Writes a mersenne_twister_engine to a @c std::ostream */ - template - friend std::basic_ostream& - operator<<(std::basic_ostream& os, - const mersenne_twister_engine& mt) + BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, mersenne_twister_engine, mt) { - mt.print(os); + UIntType data[mt.state_size]; + for (std::size_t j = 0; j < mt.i; ++j) { + data[j + mt.state_size - mt.i] = mt.x[j]; + } + if (mt.i != mt.state_size) { + mt.rewind(&data[mt.state_size - mt.i - 1], mt.state_size - mt.i); + } + os << data[0]; + for (std::size_t j = 1; j < mt.state_size; ++j) { + os << ' ' << data[j]; + } return os; } /** Reads a mersenne_twister_engine from a @c std::istream */ - template - friend std::basic_istream& - operator>>(std::basic_istream& is, - mersenne_twister_engine& mt) + BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, mersenne_twister_engine, mt) { - for(std::size_t j = 0; j < mt.state_size; ++j) - is >> mt.x[j] >> std::ws; - // MSVC (up to 7.1) and Borland (up to 5.64) don't handle the template - // value parameter "n" available from the class template scope, so use - // the static constant with the same value + is >> mt.x[0]; + for(std::size_t j = 1; j < mt.state_size; ++j) + is >> std::ws >> mt.x[j]; mt.i = mt.state_size; return is; } @@ -286,26 +289,6 @@ class mersenne_twister_engine return true; } - /** - * Does the work of operator<<. This is in a member function - * for portability. - */ - template - void print(std::basic_ostream& os) const - { - UIntType data[n]; - for(std::size_t j = 0; j < i; ++j) { - data[j + n - i] = x[j]; - } - if(i != n) { - rewind(&data[n - i - 1], n - i); - } - os << data[0]; - for(std::size_t j = 1; j < n; ++j) { - os << ' ' << data[j]; - } - } - /** * Copies z elements of the state preceding x[0] into * the array whose last element is last. diff --git a/include/boost/random/mixmax.hpp b/include/boost/random/mixmax.hpp index b3bbaf95c..670b92a86 100644 --- a/include/boost/random/mixmax.hpp +++ b/include/boost/random/mixmax.hpp @@ -121,14 +121,12 @@ class mixmax_engine{ template friend std::basic_ostream& operator<< (std::basic_ostream& ost, const mixmax_engine& me){ - ost << Ndim << " " << me.S.counter << " " << me.S.sumtot << " "; - for (int j=0; (j< (Ndim) ); j++) { - ost << (std::uint64_t)me.S.V[j] << " "; + ost << Ndim << " " << me.S.counter << " " << me.S.sumtot; + for (const std::uint64_t v: me.S.V) { + ost << " " << v; } - ost << "\n"; - ost.flush(); return ost; - } + } /** read the state of the RNG from a stream */ template @@ -141,16 +139,16 @@ class mixmax_engine{ BOOST_ASSERT(counter==Ndim); in >> counter >> std::ws; in >> savedsum >> std::ws; - for(int j=0;j> std::ws >> vec[j] ; - sum=me.MOD_MERSENNE(sum+vec[j]); - } - if (sum == savedsum && counter>0 && counter> std::ws >> v ; + sum=me.MOD_MERSENNE(sum+v); + } + if (sum == savedsum && counter>0 && counter -#include #include #include #include @@ -142,8 +141,7 @@ class splitmix64 inline friend std::basic_ostream& operator<<(std::basic_ostream& ost, const splitmix64& e) { - ost << e.state_; - return ost; + return ost << e.state_; } /** Writes a @c splitmix64 to a @c std::istream. */ @@ -151,19 +149,7 @@ class splitmix64 inline friend std::basic_istream& operator>>(std::basic_istream& ist, splitmix64& e) { - std::string sstate; - CharT val; - while (ist >> val) - { - if (std::isdigit(val)) - { - sstate.push_back(val); - } - } - - e.state_ = std::strtoull(sstate.c_str(), nullptr, 10); - - return ist; + return ist >> e.state_; } /** Fills a range with random values */ diff --git a/test/test_generator.ipp b/test/test_generator.ipp index 791a5035a..beec667b0 100644 --- a/test/test_generator.ipp +++ b/test/test_generator.ipp @@ -150,11 +150,12 @@ void do_test_streaming(const BOOST_RANDOM_URNG& urng) { BOOST_RANDOM_URNG urng2; std::basic_ostringstream output; - output << urng; + BOOST_TEST_REQUIRE(static_cast(output << urng)); BOOST_CHECK_NE(urng, urng2); // restore old state std::basic_istringstream input(output.str()); - input >> urng2; + BOOST_TEST(static_cast(input >> urng2)); + BOOST_TEST(input.eof()); BOOST_CHECK_EQUAL(urng, urng2); }