-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement LWG-3561 Issue with internal counter in `discard_block_engi…
…ne` (#4066) Co-authored-by: Stephan T. Lavavej <[email protected]>
- Loading branch information
1 parent
8d44ff0
commit 9e20399
Showing
5 changed files
with
177 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
83 changes: 83 additions & 0 deletions
83
tests/std/tests/LWG3561_discard_block_engine_counter/test.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#include <cassert> | ||
#include <climits> | ||
#include <cstddef> | ||
#include <iosfwd> | ||
#include <random> | ||
#include <sstream> | ||
#include <string> | ||
#include <type_traits> | ||
|
||
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) | ||
|
||
using namespace std; | ||
|
||
constexpr size_t large_block_size = UINT_MAX - 16; | ||
constexpr size_t large_used_block = UINT_MAX - 20; | ||
|
||
struct trivial_engine { | ||
using result_type = size_t; | ||
|
||
static constexpr size_t min() { | ||
return 0; | ||
} | ||
static constexpr size_t max() { | ||
return SIZE_MAX; | ||
} | ||
|
||
size_t operator()() noexcept { | ||
return counter_++; | ||
} | ||
|
||
#if _HAS_CXX20 | ||
friend bool operator==(const trivial_engine&, const trivial_engine&) = default; | ||
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv | ||
friend bool operator==(const trivial_engine& lhs, const trivial_engine& rhs) noexcept { | ||
return lhs.counter_ == rhs.counter_; | ||
} | ||
friend bool operator!=(const trivial_engine& lhs, const trivial_engine& rhs) noexcept { | ||
return lhs.counter_ != rhs.counter_; | ||
} | ||
#endif // ^^^ !_HAS_CXX20 ^^^ | ||
|
||
template <class CharT, class Traits> | ||
friend basic_istream<CharT, Traits>& operator>>(basic_istream<CharT, Traits>& is, trivial_engine& eng) { | ||
return is >> eng.counter_; | ||
} | ||
|
||
template <class CharT, class Traits> | ||
friend basic_ostream<CharT, Traits>& operator<<(basic_ostream<CharT, Traits>& os, const trivial_engine& eng) { | ||
return os << eng.counter_; | ||
} | ||
|
||
size_t counter_ = 0; | ||
}; | ||
|
||
using trivial_discard_block = discard_block_engine<trivial_engine, large_block_size, large_used_block>; | ||
|
||
void test_lwg_3561() { | ||
trivial_discard_block e{}; | ||
e.discard(168); | ||
auto rep = (ostringstream{} << e).str(); | ||
|
||
assert(e == e); | ||
assert(!(e != e)); | ||
assert(rep == "168 168"); // relies on the implementation-specific details of operator<< | ||
} | ||
|
||
// Also tests the type correctness of discard_block_engine::block_size/used_block | ||
|
||
STATIC_ASSERT(is_same_v<const size_t, decltype(trivial_discard_block::block_size)>); | ||
STATIC_ASSERT(is_same_v<const size_t, decltype(trivial_discard_block::used_block)>); | ||
|
||
STATIC_ASSERT(is_same_v<const size_t, decltype(ranlux24::block_size)>); | ||
STATIC_ASSERT(is_same_v<const size_t, decltype(ranlux24::used_block)>); | ||
|
||
STATIC_ASSERT(is_same_v<const size_t, decltype(ranlux48::block_size)>); | ||
STATIC_ASSERT(is_same_v<const size_t, decltype(ranlux48::used_block)>); | ||
|
||
int main() { | ||
test_lwg_3561(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters