Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 57 additions & 3 deletions stl/inc/random
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <iosfwd>
#include <ios>
#include <vector>
#include <xbit_ops.h>
#include <xstring>
Expand Down Expand Up @@ -674,6 +674,12 @@ public:
return _Ostr;
}

template <class _Elem, class _Traits>
basic_ostream<_Elem, _Traits>& _Write_full(basic_ostream<_Elem, _Traits>& _Ostr) const { // write state to _Ostr
_Swc_Traits::_Write_full(_Ostr, *this, _Carry);
return _Ostr;
}

protected:
template <class _Gen>
void _Seed(_Gen& _Gx, bool _Readcy, true_type) { // reset sequence from numeric value
Expand Down Expand Up @@ -816,14 +822,24 @@ struct _Swc_traits { // traits for subtract_with_carry generator
int _Kx = _Get_wc();

for (size_t _Ix = 0; _Ix < _Nw; ++_Ix) {
for (int _Jx = 1; _Jx <= _Kx; ++_Jx) { // unpack into _Kx words
unsigned int _Word = static_cast<unsigned int>(_Buf._At(_Ix) >> ((_Kx - _Jx) * 32));
for (int _Jx = 0; _Jx < _Kx; ++_Jx) { // unpack into _Kx words
const unsigned int _Word = static_cast<unsigned int>(_Buf._At(_Ix) >> (_Jx * 32));
Comment on lines -819 to +826

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for other reviewers (no change requested): as the runtime behavior here was completely messed up, I am okay with changing the serialized output.

_Ostr << _Word << ' ';
}
}

_Ostr << _Cy;
}

template <class _Elem, class _Traits>
static void _Write_full(
basic_ostream<_Elem, _Traits>& _Ostr, const _Circ_buf<_Ty, _Nw>& _Buf, _Cy_t _Cy) { // write state to _Ostr
for (size_t _Ix = 0; _Ix < _Nw; ++_Ix) {
_Ostr << _Buf._At(_Ix) << ' ';
}

_Ostr << _Cy;
}
};

template <class _Ty, _Ty _Mx, size_t _Sx, size_t _Rx>
Expand Down Expand Up @@ -908,6 +924,44 @@ public:
_NODISCARD static constexpr _Ty(max)() {
return _Mx - 1;
}

template <class _Elem, class _Traits>
friend basic_ostream<_Elem, _Traits>& operator<<(
basic_ostream<_Elem, _Traits>& _Ostr, const subtract_with_carry_engine& _Eng) {
const auto _Save_flags = _Ostr.flags(ios_base::dec | ios_base::left);
const auto _Save_fill = _Ostr.fill(' ');
_Eng._Write_full(_Ostr);
_Ostr.flags(_Save_flags);
_Ostr.fill(_Save_fill);
return _Ostr;
}

template <class _Elem, class _Traits>
friend basic_istream<_Elem, _Traits>& operator>>(
basic_istream<_Elem, _Traits>& _Istr, subtract_with_carry_engine& _Eng) {
constexpr auto _Nx = long_lag;
result_type _Buffer[_Nx];
typename _Mybase::_Traits::_Cy_t _Carry_buf;
const auto _Save_flags = _Istr.flags(ios_base::dec | ios_base::skipws);
for (size_t _Ix = 0; _Ix < _Nx; ++_Ix) {
_Istr >> _Buffer[_Ix];
}

_Istr >> _Carry_buf;
if (_Istr) {
for (size_t _Ix = 0; _Ix < _Nx; ++_Ix) {
_Eng._Ax[_Ix] = _Buffer[_Ix];
}

_Eng._Carry = _Carry_buf;
_Eng._Idx = _Nx;
} else {
_Istr.setstate(ios_base::failbit);
}

_Istr.flags(_Save_flags);
return _Istr;
}
};

#if _HAS_TR1_NAMESPACE
Expand Down
13 changes: 0 additions & 13 deletions tests/libcxx/expected_results.txt
Original file line number Diff line number Diff line change
Expand Up @@ -779,19 +779,6 @@ std/input.output/iostream.format/ext.manip/get_money.pass.cpp FAIL
std/input.output/iostream.format/ext.manip/put_money.pass.cpp FAIL
std/input.output/iostreams.base/ios/basic.ios.members/copyfmt.pass.cpp FAIL

# Not yet analyzed, likely STL bugs. Assertion failed: os.str() == a
std/numerics/rand/rand.adapt/rand.adapt.disc/ctor_result_type.pass.cpp FAIL
std/numerics/rand/rand.adapt/rand.adapt.disc/ctor_sseq.pass.cpp FAIL
std/numerics/rand/rand.adapt/rand.adapt.ibits/ctor_result_type.pass.cpp FAIL
std/numerics/rand/rand.adapt/rand.adapt.ibits/ctor_sseq.pass.cpp FAIL
std/numerics/rand/rand.eng/rand.eng.sub/ctor_result_type.pass.cpp FAIL
std/numerics/rand/rand.eng/rand.eng.sub/ctor_sseq.pass.cpp FAIL

# Not yet analyzed, likely STL bugs. Assertion failed: e1 == e2
std/numerics/rand/rand.adapt/rand.adapt.disc/io.pass.cpp FAIL
std/numerics/rand/rand.adapt/rand.adapt.ibits/io.pass.cpp FAIL
std/numerics/rand/rand.eng/rand.eng.sub/io.pass.cpp FAIL

# Likely STL bug: Looks like we shouldn't be using assignment.
std/thread/futures/futures.promise/set_rvalue.pass.cpp FAIL

Expand Down
13 changes: 0 additions & 13 deletions tests/libcxx/skipped_tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -779,19 +779,6 @@ input.output\iostream.format\ext.manip\get_money.pass.cpp
input.output\iostream.format\ext.manip\put_money.pass.cpp
input.output\iostreams.base\ios\basic.ios.members\copyfmt.pass.cpp

# Not yet analyzed, likely STL bugs. Assertion failed: os.str() == a
numerics\rand\rand.adapt\rand.adapt.disc\ctor_result_type.pass.cpp
numerics\rand\rand.adapt\rand.adapt.disc\ctor_sseq.pass.cpp
numerics\rand\rand.adapt\rand.adapt.ibits\ctor_result_type.pass.cpp
numerics\rand\rand.adapt\rand.adapt.ibits\ctor_sseq.pass.cpp
numerics\rand\rand.eng\rand.eng.sub\ctor_result_type.pass.cpp
numerics\rand\rand.eng\rand.eng.sub\ctor_sseq.pass.cpp

# Not yet analyzed, likely STL bugs. Assertion failed: e1 == e2
numerics\rand\rand.adapt\rand.adapt.disc\io.pass.cpp
numerics\rand\rand.adapt\rand.adapt.ibits\io.pass.cpp
numerics\rand\rand.eng\rand.eng.sub\io.pass.cpp

# Likely STL bug: Looks like we shouldn't be using assignment.
thread\futures\futures.promise\set_rvalue.pass.cpp

Expand Down
1 change: 1 addition & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ tests\GH_000431_equal_memcmp_is_safe
tests\GH_000431_iter_copy_move_cat
tests\GH_000431_lex_compare_family
tests\GH_000431_lex_compare_memcmp_classify
tests\GH_000442_random_subtract_with_carry_engine_io
tests\GH_000457_system_error_message
tests\GH_000545_include_compare
tests\GH_000625_vector_bool_optimization
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\usual_matrix.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <cassert>
#include <cstddef>
#include <ios>
#include <random>
#include <sstream>
#include <string>
using namespace std;

void check_state(const string& state_str) {
// Check word-by-word in case of whitespace differences.
static constexpr const char* state_ref[] = {
"10880375256626",
"126660097854724",
"33643165434010",
"78293780235492",
"179418984296008",
"96783156950859",
"238199764491708",
"34339434557790",
"155299155394531",
"29014415493780",
"209265474179052",
"263777435457028",
"0",
};
constexpr auto state_size = size(state_ref);
stringstream sstr(state_str);

size_t idx = 0;
string word;
while (sstr && idx < state_size) {
sstr >> word;
assert(word == state_ref[idx]);
++idx;
}

assert(sstr.rdstate() == ios_base::eofbit);
assert(idx == state_size);
}

void check(stringstream& sstr) {
// N4892 [tab:rand.req.eng]: "Postconditions: The os.fmtflags and fill character are unchanged."
// and "Postconditions: The is.fmtflags are unchanged."
const auto old_flags = sstr.flags();
const auto old_fill = sstr.fill();
ranlux48_base eng1;
ranlux48_base eng2;
sstr << eng1;
check_state(sstr.str());
sstr >> eng2;
assert(eng1 == eng2);
assert(sstr.flags() == old_flags);
assert(sstr.fill() == old_fill);
}

int main() {
{
stringstream sstr;
sstr << hex;
check(sstr);
}

{
stringstream sstr;
sstr.unsetf(ios_base::skipws);
check(sstr);
}

{
stringstream sstr;
sstr.fill('.');
sstr.width(40);
check(sstr);
}

return 0;
}