From 1bd796a4f988635d3359a7576d2fbd2700f9d78d Mon Sep 17 00:00:00 2001 From: statementreply Date: Thu, 9 Jul 2020 23:10:01 +0800 Subject: [PATCH 1/9] Fix discrete_distribution result out of range Mathematically, _Par0._Pcdf.back() should be one. However, when it is actually slightly smaller than one due to rounding error, there is a small probability that _Px > _Par0._Pcdf.back() and the original code returns the invalid value of _Par0._Pcdf.size(). --- stl/inc/random | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/random b/stl/inc/random index 4427cd637a5..371b9dc645d 100644 --- a/stl/inc/random +++ b/stl/inc/random @@ -4507,7 +4507,7 @@ private: result_type _Eval(_Engine& _Eng, const param_type& _Par0) const { double _Px = _NRAND(_Eng, double); const auto _First = _Par0._Pcdf.begin(); - const auto _Position = _STD lower_bound(_First, _Par0._Pcdf.end(), _Px); + const auto _Position = _STD lower_bound(_First, _STD prev(_Par0._Pcdf.end()), _Px); return static_cast(_Position - _First); } From 786e7aaeff80aad7ac35c6e0b2cc7bd573c7dc83 Mon Sep 17 00:00:00 2001 From: statementreply Date: Fri, 10 Jul 2020 08:03:00 +0800 Subject: [PATCH 2/9] Update stl/inc/random Use _Prev_iter Co-authored-by: Casey Carter --- stl/inc/random | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/random b/stl/inc/random index 371b9dc645d..47ceeab3e55 100644 --- a/stl/inc/random +++ b/stl/inc/random @@ -4507,7 +4507,7 @@ private: result_type _Eval(_Engine& _Eng, const param_type& _Par0) const { double _Px = _NRAND(_Eng, double); const auto _First = _Par0._Pcdf.begin(); - const auto _Position = _STD lower_bound(_First, _STD prev(_Par0._Pcdf.end()), _Px); + const auto _Position = _STD lower_bound(_First, _Prev_iter(_Par0._Pcdf.end()), _Px); return static_cast(_Position - _First); } From b71dc47d7f9b1b06562ef3c99b128bda46ae238f Mon Sep 17 00:00:00 2001 From: statementreply Date: Fri, 10 Jul 2020 22:45:26 +0800 Subject: [PATCH 3/9] Add regression test --- tests/std/include/bad_random_engine.hpp | 158 ++++++++++++++++++ tests/std/test.lst | 1 + .../env.lst | 4 + .../test.cpp | 17 ++ 4 files changed, 180 insertions(+) create mode 100644 tests/std/include/bad_random_engine.hpp create mode 100644 tests/std/tests/GH_001017_discrete_distribution_out_of_range/env.lst create mode 100644 tests/std/tests/GH_001017_discrete_distribution_out_of_range/test.cpp diff --git a/tests/std/include/bad_random_engine.hpp b/tests/std/include/bad_random_engine.hpp new file mode 100644 index 00000000000..34423387fc2 --- /dev/null +++ b/tests/std/include/bad_random_engine.hpp @@ -0,0 +1,158 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#pragma once + +#include +#include +#include +#include + +namespace detail { + template ::digits> + class bad_rng_bit_generator { // generates bit patterns for bad_random_engine + public: + using result_type = UInt; + + static constexpr result_type top_bit = result_type{1} << (Width - 1); + static constexpr result_type lower_bits = top_bit - 1; + static constexpr result_type mask_bits = top_bit | lower_bits; + static constexpr int final_bit_count = (Width - 1) / 2 + 1; + + constexpr result_type current_value() const noexcept { // gets the current pattern + return current_value_; + } + + constexpr bool generate_next() noexcept { // generates the next pattern, returns false if back to all 0's + current_value_ = (current_value_ & lower_bits) << 1 | (current_value_ & top_bit) >> (Width - 1); + + if (current_shift < Width - 1 && current_bit_count != 0 && current_bit_count != Width) { + ++current_shift; + return true; + } + + current_shift = 0; + + if (current_bit_count < final_bit_count) { // n 1's -> n 0's + current_bit_count = Width - current_bit_count; + current_value_ ^= mask_bits; + return true; + } else if (current_bit_count > final_bit_count) { // n 0's -> (n+1) 1's + current_bit_count = Width - current_bit_count + 1; + current_value_ = (current_value_ ^ mask_bits) << 1 | result_type{1}; + return true; + } else { // all bit patterns have been generated, back to all 0's + current_bit_count = 0; + current_value_ = result_type{0}; + return false; + } + } + + friend constexpr bool operator==(const bad_rng_bit_generator& a, const bad_rng_bit_generator& b) noexcept { + return a.current_value() == b.current_value(); + } + + friend constexpr bool operator!=(const bad_rng_bit_generator& a, const bad_rng_bit_generator& b) noexcept { + return !(a == b); + } + + private: + result_type current_value_ = 0; + int current_bit_count = 0; + int current_shift = 0; + }; +} // namespace detail + +template ::digits, int Dimension = 1> +class bad_random_engine { + // Generates bit patterns with at most two transitions between 0's and 1's. + // (e.g. 00000000, 11111111, 00001111, 11110000, 00011000, 11100111) + // When its output is grouped into subsequences of length Dimension, it cycles through all possible subsequences + // containing only such bit patterns. Bit patterns with few 1's or few 0's are be generated first, starting from + // all 0's and all 1's. + + static_assert(std::is_integral::value, "bad_random_engine: UInt should be unsigned integeral type"); + static_assert(std::is_unsigned::value, "bad_random_engine: UInt should be unsigned integeral type"); + static_assert(Width > 0, "bad_random_engine: invalid value for Width"); + static_assert(Width <= std::numeric_limits::digits, "bad_random_engine: invalid value for Width"); + static_assert(Dimension > 0, "bad_random_engine: invalid value for Dimension"); + + +public: + using result_type = UInt; + + static constexpr result_type(min)() noexcept { + return result_type{0}; + } + static constexpr result_type(max)() noexcept { + return generator::mask_bits; + } + + constexpr result_type operator()() noexcept { + const result_type result = generators[current_dimension].current_value(); + + if (current_dimension < Dimension - 1) { + ++current_dimension; + } else { + current_dimension = 0; + + if (!generate_next()) { + has_cycled_through_ = true; + } + } + + return result; + } + + constexpr bool has_cycled_through() const noexcept { // have we finished a full cycle? + return has_cycled_through_; + } + +private: + using generator = detail::bad_rng_bit_generator; + + constexpr bool generate_next() noexcept { // generates the next subsequence, returns false if back to all 0's + if (limit_value != generator{}) { + for (int i = 0; i < limit_dimension; ++i) { + if (generators[i] != limit_value) { + generators[i].generate_next(); + return true; + } else { + generators[i] = generator{}; + } + } + + for (int i = limit_dimension + 1; i < Dimension; ++i) { + generators[i].generate_next(); + if (generators[i] != limit_value) { + return true; + } else { + generators[i] = generator{}; + } + } + + __analysis_assume(limit_dimension < Dimension); + generators[limit_dimension] = generator{}; + + if (limit_dimension < Dimension - 1) { + ++limit_dimension; + generators[limit_dimension] = limit_value; + return true; + } + } + + limit_dimension = 0; + const bool result = limit_value.generate_next(); + generators[0] = limit_value; + return result; + } + + generator generators[Dimension] = {}; + generator limit_value{}; + int limit_dimension = 0; + int current_dimension = 0; + bool has_cycled_through_ = false; +}; + +// the cycle length of bad_random_generator is 32 546 312 +using bad_random_generator = bad_random_engine; diff --git a/tests/std/test.lst b/tests/std/test.lst index 98930beaa8b..c086ea2bb77 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -160,6 +160,7 @@ tests\GH_000545_include_compare tests\GH_000685_condition_variable_any tests\GH_000690_overaligned_function tests\GH_000890_pow_template +tests\GH_001017_discrete_distribution_out_of_range tests\LWG2597_complex_branch_cut tests\LWG3018_shared_ptr_function tests\P0024R2_parallel_algorithms_adjacent_difference diff --git a/tests/std/tests/GH_001017_discrete_distribution_out_of_range/env.lst b/tests/std/tests/GH_001017_discrete_distribution_out_of_range/env.lst new file mode 100644 index 00000000000..19f025bd0e6 --- /dev/null +++ b/tests/std/tests/GH_001017_discrete_distribution_out_of_range/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_matrix.lst diff --git a/tests/std/tests/GH_001017_discrete_distribution_out_of_range/test.cpp b/tests/std/tests/GH_001017_discrete_distribution_out_of_range/test.cpp new file mode 100644 index 00000000000..f5323d93e92 --- /dev/null +++ b/tests/std/tests/GH_001017_discrete_distribution_out_of_range/test.cpp @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include + +#include + +int main() { + std::discrete_distribution dist{1, 1, 1, 1, 1, 1}; + bad_random_generator rng; + + while (!rng.has_cycled_through()) { + const auto rand_value = dist(rng); + assert(0 <= rand_value && rand_value < 6); + } +} From 9716e013c4cc67073fa3730b087dab461ca885c9 Mon Sep 17 00:00:00 2001 From: statementreply Date: Sat, 11 Jul 2020 00:24:23 +0800 Subject: [PATCH 4/9] tests: Make bad_rng_pattern_generator a forward iterator --- tests/std/include/bad_random_engine.hpp | 96 +++++++++++++++++-------- 1 file changed, 65 insertions(+), 31 deletions(-) diff --git a/tests/std/include/bad_random_engine.hpp b/tests/std/include/bad_random_engine.hpp index 34423387fc2..0b8202525ca 100644 --- a/tests/std/include/bad_random_engine.hpp +++ b/tests/std/include/bad_random_engine.hpp @@ -9,26 +9,38 @@ #include namespace detail { + struct bad_rng_pattern_sentinel {}; + template ::digits> - class bad_rng_bit_generator { // generates bit patterns for bad_random_engine + class bad_rng_pattern_generator { // generates bit patterns for bad_random_engine public: - using result_type = UInt; - - static constexpr result_type top_bit = result_type{1} << (Width - 1); - static constexpr result_type lower_bits = top_bit - 1; - static constexpr result_type mask_bits = top_bit | lower_bits; - static constexpr int final_bit_count = (Width - 1) / 2 + 1; - - constexpr result_type current_value() const noexcept { // gets the current pattern + using difference_type = std::ptrdiff_t; + using value_type = UInt; + using pointer = const UInt*; + using reference = const UInt&; + using iterator_category = std::forward_iterator_tag; + using my_iter = bad_rng_pattern_generator; + using my_sentinel = bad_rng_pattern_sentinel; + + static constexpr value_type top_bit = value_type{1} << (Width - 1); + static constexpr value_type lower_bits = top_bit - 1; + static constexpr value_type mask_bits = top_bit | lower_bits; + static constexpr int final_bit_count = (Width - 1) / 2 + 1; + + constexpr reference operator*() const noexcept { // gets the current pattern return current_value_; } - constexpr bool generate_next() noexcept { // generates the next pattern, returns false if back to all 0's + constexpr pointer operator->() const noexcept { + return ¤t_value_; + } + + constexpr my_iter& operator++() noexcept { // generates the next pattern current_value_ = (current_value_ & lower_bits) << 1 | (current_value_ & top_bit) >> (Width - 1); if (current_shift < Width - 1 && current_bit_count != 0 && current_bit_count != Width) { ++current_shift; - return true; + return *this; } current_shift = 0; @@ -36,30 +48,52 @@ namespace detail { if (current_bit_count < final_bit_count) { // n 1's -> n 0's current_bit_count = Width - current_bit_count; current_value_ ^= mask_bits; - return true; } else if (current_bit_count > final_bit_count) { // n 0's -> (n+1) 1's current_bit_count = Width - current_bit_count + 1; - current_value_ = (current_value_ ^ mask_bits) << 1 | result_type{1}; - return true; + current_value_ = (current_value_ ^ mask_bits) << 1 | value_type{1}; } else { // all bit patterns have been generated, back to all 0's current_bit_count = 0; - current_value_ = result_type{0}; - return false; + current_value_ = value_type{0}; } + + return *this; + } + + constexpr my_iter operator++(int) noexcept { + const my_iter old = *this; + ++*this; + return old; } - friend constexpr bool operator==(const bad_rng_bit_generator& a, const bad_rng_bit_generator& b) noexcept { - return a.current_value() == b.current_value(); + friend constexpr bool operator==(const my_iter& a, const my_iter& b) noexcept { + return *a == *b; } - friend constexpr bool operator!=(const bad_rng_bit_generator& a, const bad_rng_bit_generator& b) noexcept { + friend constexpr bool operator!=(const my_iter& a, const my_iter& b) noexcept { return !(a == b); } + friend constexpr bool operator==(const my_iter& iter, const my_sentinel sentinel) noexcept { + (void) sentinel; + return *iter == 0; + } + + friend constexpr bool operator!=(const my_iter& iter, const my_sentinel sentinel) noexcept { + return !(iter == sentinel); + } + + friend constexpr bool operator==(const my_sentinel sentinel, const my_iter& iter) noexcept { + return iter == sentinel; + } + + friend constexpr bool operator!=(const my_sentinel sentinel, const my_iter& iter) noexcept { + return !(iter == sentinel); + } + private: - result_type current_value_ = 0; - int current_bit_count = 0; - int current_shift = 0; + value_type current_value_ = 0; + int current_bit_count = 0; + int current_shift = 0; }; } // namespace detail @@ -89,7 +123,7 @@ class bad_random_engine { } constexpr result_type operator()() noexcept { - const result_type result = generators[current_dimension].current_value(); + const result_type result = *generators[current_dimension]; if (current_dimension < Dimension - 1) { ++current_dimension; @@ -109,13 +143,14 @@ class bad_random_engine { } private: - using generator = detail::bad_rng_bit_generator; + using generator = detail::bad_rng_pattern_generator; + using sentinel = detail::bad_rng_pattern_sentinel; constexpr bool generate_next() noexcept { // generates the next subsequence, returns false if back to all 0's - if (limit_value != generator{}) { + if (limit_value != sentinel{}) { for (int i = 0; i < limit_dimension; ++i) { if (generators[i] != limit_value) { - generators[i].generate_next(); + ++generators[i]; return true; } else { generators[i] = generator{}; @@ -123,7 +158,7 @@ class bad_random_engine { } for (int i = limit_dimension + 1; i < Dimension; ++i) { - generators[i].generate_next(); + ++generators[i]; if (generators[i] != limit_value) { return true; } else { @@ -141,10 +176,9 @@ class bad_random_engine { } } - limit_dimension = 0; - const bool result = limit_value.generate_next(); - generators[0] = limit_value; - return result; + limit_dimension = 0; + generators[0] = ++limit_value; + return limit_value != sentinel{}; } generator generators[Dimension] = {}; From 009dbf1e707484d46520f7645d8da17df8425263 Mon Sep 17 00:00:00 2001 From: statementreply Date: Sat, 11 Jul 2020 13:31:54 +0800 Subject: [PATCH 5/9] Fix comment typo --- tests/std/include/bad_random_engine.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/std/include/bad_random_engine.hpp b/tests/std/include/bad_random_engine.hpp index 0b8202525ca..971bc5f101c 100644 --- a/tests/std/include/bad_random_engine.hpp +++ b/tests/std/include/bad_random_engine.hpp @@ -102,8 +102,8 @@ class bad_random_engine { // Generates bit patterns with at most two transitions between 0's and 1's. // (e.g. 00000000, 11111111, 00001111, 11110000, 00011000, 11100111) // When its output is grouped into subsequences of length Dimension, it cycles through all possible subsequences - // containing only such bit patterns. Bit patterns with few 1's or few 0's are be generated first, starting from - // all 0's and all 1's. + // containing only such bit patterns. Bit patterns with few 1's or few 0's are generated first, starting from all + // 0's and all 1's. static_assert(std::is_integral::value, "bad_random_engine: UInt should be unsigned integeral type"); static_assert(std::is_unsigned::value, "bad_random_engine: UInt should be unsigned integeral type"); From e009f03f341f736892428f7572573912c863e28d Mon Sep 17 00:00:00 2001 From: statementreply Date: Sat, 18 Jul 2020 21:09:05 +0800 Subject: [PATCH 6/9] Minor fixes --- tests/std/include/bad_random_engine.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/include/bad_random_engine.hpp b/tests/std/include/bad_random_engine.hpp index 971bc5f101c..dcb630ee92a 100644 --- a/tests/std/include/bad_random_engine.hpp +++ b/tests/std/include/bad_random_engine.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -111,7 +112,6 @@ class bad_random_engine { static_assert(Width <= std::numeric_limits::digits, "bad_random_engine: invalid value for Width"); static_assert(Dimension > 0, "bad_random_engine: invalid value for Dimension"); - public: using result_type = UInt; From 7873c706003494afb988d2a75bd5c79a5a5f9c6d Mon Sep 17 00:00:00 2001 From: statementreply Date: Thu, 23 Jul 2020 20:45:56 +0800 Subject: [PATCH 7/9] Address review comments --- .../bad_random_engine.hpp | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) rename tests/std/{include => tests/GH_001017_discrete_distribution_out_of_range}/bad_random_engine.hpp (70%) diff --git a/tests/std/include/bad_random_engine.hpp b/tests/std/tests/GH_001017_discrete_distribution_out_of_range/bad_random_engine.hpp similarity index 70% rename from tests/std/include/bad_random_engine.hpp rename to tests/std/tests/GH_001017_discrete_distribution_out_of_range/bad_random_engine.hpp index dcb630ee92a..5d9a55450b1 100644 --- a/tests/std/include/bad_random_engine.hpp +++ b/tests/std/tests/GH_001017_discrete_distribution_out_of_range/bad_random_engine.hpp @@ -19,7 +19,7 @@ namespace detail { using value_type = UInt; using pointer = const UInt*; using reference = const UInt&; - using iterator_category = std::forward_iterator_tag; + using iterator_category = std::input_iterator_tag; using my_iter = bad_rng_pattern_generator; using my_sentinel = bad_rng_pattern_sentinel; @@ -39,22 +39,22 @@ namespace detail { constexpr my_iter& operator++() noexcept { // generates the next pattern current_value_ = (current_value_ & lower_bits) << 1 | (current_value_ & top_bit) >> (Width - 1); - if (current_shift < Width - 1 && current_bit_count != 0 && current_bit_count != Width) { - ++current_shift; + if (current_shift_ < Width - 1 && current_bit_count_ != 0 && current_bit_count_ != Width) { + ++current_shift_; return *this; } - current_shift = 0; + current_shift_ = 0; - if (current_bit_count < final_bit_count) { // n 1's -> n 0's - current_bit_count = Width - current_bit_count; + if (current_bit_count_ < final_bit_count) { // n 1's -> n 0's + current_bit_count_ = Width - current_bit_count_; current_value_ ^= mask_bits; - } else if (current_bit_count > final_bit_count) { // n 0's -> (n+1) 1's - current_bit_count = Width - current_bit_count + 1; - current_value_ = (current_value_ ^ mask_bits) << 1 | value_type{1}; + } else if (current_bit_count_ > final_bit_count) { // n 0's -> (n+1) 1's + current_bit_count_ = Width - current_bit_count_ + 1; + current_value_ = (current_value_ ^ mask_bits) << 1 | value_type{1}; } else { // all bit patterns have been generated, back to all 0's - current_bit_count = 0; - current_value_ = value_type{0}; + current_bit_count_ = 0; + current_value_ = value_type{0}; } return *this; @@ -93,8 +93,8 @@ namespace detail { private: value_type current_value_ = 0; - int current_bit_count = 0; - int current_shift = 0; + int current_bit_count_ = 0; + int current_shift_ = 0; }; } // namespace detail @@ -123,12 +123,12 @@ class bad_random_engine { } constexpr result_type operator()() noexcept { - const result_type result = *generators[current_dimension]; + const result_type result = *generators_[current_dimension_]; - if (current_dimension < Dimension - 1) { - ++current_dimension; + if (current_dimension_ < Dimension - 1) { + ++current_dimension_; } else { - current_dimension = 0; + current_dimension_ = 0; if (!generate_next()) { has_cycled_through_ = true; @@ -147,44 +147,44 @@ class bad_random_engine { using sentinel = detail::bad_rng_pattern_sentinel; constexpr bool generate_next() noexcept { // generates the next subsequence, returns false if back to all 0's - if (limit_value != sentinel{}) { - for (int i = 0; i < limit_dimension; ++i) { - if (generators[i] != limit_value) { - ++generators[i]; + if (limit_value_ != sentinel{}) { + for (int i = 0; i < limit_dimension_; ++i) { + if (generators_[i] != limit_value_) { + ++generators_[i]; return true; } else { - generators[i] = generator{}; + generators_[i] = generator{}; } } - for (int i = limit_dimension + 1; i < Dimension; ++i) { - ++generators[i]; - if (generators[i] != limit_value) { + for (int i = limit_dimension_ + 1; i < Dimension; ++i) { + ++generators_[i]; + if (generators_[i] != limit_value_) { return true; } else { - generators[i] = generator{}; + generators_[i] = generator{}; } } - __analysis_assume(limit_dimension < Dimension); - generators[limit_dimension] = generator{}; + __analysis_assume(limit_dimension_ < Dimension); + generators_[limit_dimension_] = generator{}; - if (limit_dimension < Dimension - 1) { - ++limit_dimension; - generators[limit_dimension] = limit_value; + if (limit_dimension_ < Dimension - 1) { + ++limit_dimension_; + generators_[limit_dimension_] = limit_value_; return true; } } - limit_dimension = 0; - generators[0] = ++limit_value; - return limit_value != sentinel{}; + limit_dimension_ = 0; + generators_[0] = ++limit_value_; + return limit_value_ != sentinel{}; } - generator generators[Dimension] = {}; - generator limit_value{}; - int limit_dimension = 0; - int current_dimension = 0; + generator generators_[Dimension] = {}; + generator limit_value_{}; + int limit_dimension_ = 0; + int current_dimension_ = 0; bool has_cycled_through_ = false; }; From 7036941fe3120765d7783d3a5204f7fdfedd3611 Mon Sep 17 00:00:00 2001 From: statementreply Date: Thu, 23 Jul 2020 21:56:09 +0800 Subject: [PATCH 8/9] Update #include after moving header file --- .../tests/GH_001017_discrete_distribution_out_of_range/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/GH_001017_discrete_distribution_out_of_range/test.cpp b/tests/std/tests/GH_001017_discrete_distribution_out_of_range/test.cpp index f5323d93e92..5a43af9b4df 100644 --- a/tests/std/tests/GH_001017_discrete_distribution_out_of_range/test.cpp +++ b/tests/std/tests/GH_001017_discrete_distribution_out_of_range/test.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include "bad_random_engine.hpp" int main() { std::discrete_distribution dist{1, 1, 1, 1, 1, 1}; From 22bf422d00cea85646aa7e5ad684f11707da293d Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 25 Jul 2020 16:52:20 -0700 Subject: [PATCH 9/9] Apply suggestions from code review --- .../bad_random_engine.hpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/std/tests/GH_001017_discrete_distribution_out_of_range/bad_random_engine.hpp b/tests/std/tests/GH_001017_discrete_distribution_out_of_range/bad_random_engine.hpp index 5d9a55450b1..d57d20bb641 100644 --- a/tests/std/tests/GH_001017_discrete_distribution_out_of_range/bad_random_engine.hpp +++ b/tests/std/tests/GH_001017_discrete_distribution_out_of_range/bad_random_engine.hpp @@ -74,8 +74,7 @@ namespace detail { return !(a == b); } - friend constexpr bool operator==(const my_iter& iter, const my_sentinel sentinel) noexcept { - (void) sentinel; + friend constexpr bool operator==(const my_iter& iter, my_sentinel) noexcept { return *iter == 0; } @@ -106,8 +105,8 @@ class bad_random_engine { // containing only such bit patterns. Bit patterns with few 1's or few 0's are generated first, starting from all // 0's and all 1's. - static_assert(std::is_integral::value, "bad_random_engine: UInt should be unsigned integeral type"); - static_assert(std::is_unsigned::value, "bad_random_engine: UInt should be unsigned integeral type"); + static_assert(std::is_integral_v, "bad_random_engine: UInt should be unsigned integral type"); + static_assert(std::is_unsigned_v, "bad_random_engine: UInt should be unsigned integral type"); static_assert(Width > 0, "bad_random_engine: invalid value for Width"); static_assert(Width <= std::numeric_limits::digits, "bad_random_engine: invalid value for Width"); static_assert(Dimension > 0, "bad_random_engine: invalid value for Dimension");