On 15/05/18 16:36 +0100, Jonathan Wakely wrote:
Constrain constructors and member functions of random number engines so
that functions taking seed sequences can only be called with types that
meet the seed sequence requirements.
PR libstdc++/85749
* include/bits/random.h (__detail::__is_seed_seq): New SFINAE helper.
(linear_congruential_engine, mersenne_twister_engine)
(subtract_with_carry_engine, discard_block_engine)
(independent_bits_engine, shuffle_order_engine): Use __is_seed_seq to
constrain function templates taking seed sequences.
* include/bits/random.tcc (linear_congruential_engine::seed(_Sseq&))
(mersenne_twister_engine::seed(_Sseq&))
(subtract_with_carry_engine::seed(_Sseq&)): Change return types to
match declarations.
* include/ext/random (simd_fast_mersenne_twister_engine): Use
__is_seed_seq to constrain function templates taking seed sequences.
* include/ext/random.tcc (simd_fast_mersenne_twister_engine::seed):
Change return type to match declaration.
* testsuite/26_numerics/random/discard_block_engine/cons/seed_seq2.cc:
New.
* testsuite/26_numerics/random/independent_bits_engine/cons/
seed_seq2.cc: New.
* testsuite/26_numerics/random/linear_congruential_engine/cons/
seed_seq2.cc: New.
* testsuite/26_numerics/random/mersenne_twister_engine/cons/
seed_seq2.cc: New.
* testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error lineno.
* testsuite/26_numerics/random/shuffle_order_engine/cons/seed_seq2.cc:
New.
* testsuite/26_numerics/random/subtract_with_carry_engine/cons/
seed_seq2.cc: New.
* testsuite/ext/random/simd_fast_mersenne_twister_engine/cons/
seed_seq2.cc: New.
Tested powerpc64le-linux, committed to trunk.
commit 2197343e0cb9439687e453f37bf9ea2908bd499d
Author: Jonathan Wakely <jwak...@redhat.com>
Date: Sat May 12 00:22:23 2018 +0100
PR libstdc++/85749 constrain seed sequences for random number engines
Constrain constructors and member functions of random number engines so
that functions taking seed sequences can only be called with types that
meet the seed sequence requirements.
PR libstdc++/85749
* include/bits/random.h (__detail::__is_seed_seq): New SFINAE helper.
(linear_congruential_engine, mersenne_twister_engine)
(subtract_with_carry_engine, discard_block_engine)
(independent_bits_engine, shuffle_order_engine): Use __is_seed_seq to
constrain function templates taking seed sequences.
* include/bits/random.tcc (linear_congruential_engine::seed(_Sseq&))
(mersenne_twister_engine::seed(_Sseq&))
(subtract_with_carry_engine::seed(_Sseq&)): Change return types to
match declarations.
* include/ext/random (simd_fast_mersenne_twister_engine): Use
__is_seed_seq to constrain function templates taking seed sequences.
* include/ext/random.tcc (simd_fast_mersenne_twister_engine::seed):
Change return type to match declaration.
*
testsuite/26_numerics/random/discard_block_engine/cons/seed_seq2.cc:
New.
* testsuite/26_numerics/random/independent_bits_engine/cons/
seed_seq2.cc: New.
* testsuite/26_numerics/random/linear_congruential_engine/cons/
seed_seq2.cc: New.
* testsuite/26_numerics/random/mersenne_twister_engine/cons/
seed_seq2.cc: New.
* testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error
lineno.
*
testsuite/26_numerics/random/shuffle_order_engine/cons/seed_seq2.cc:
New.
* testsuite/26_numerics/random/subtract_with_carry_engine/cons/
seed_seq2.cc: New.
* testsuite/ext/random/simd_fast_mersenne_twister_engine/cons/
seed_seq2.cc: New.
diff --git a/libstdc++-v3/include/bits/random.h
b/libstdc++-v3/include/bits/random.h
index f812bbf18b1..b76cfbb558e 100644
--- a/libstdc++-v3/include/bits/random.h
+++ b/libstdc++-v3/include/bits/random.h
@@ -185,6 +185,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Engine& _M_g;
};
+ template<typename _Sseq>
+ using __seed_seq_generate_t = decltype(
+ std::declval<_Sseq&>().generate(std::declval<uint_least32_t*>(),
+ std::declval<uint_least32_t*>()));
+
+ // Detect whether _Sseq is a valid seed sequence for
+ // a random number engine _Engine with result type _Res.
+ template<typename _Sseq, typename _Engine, typename _Res,
+ typename _GenerateCheck = __seed_seq_generate_t<_Sseq>>
+ using __is_seed_seq = __and_<
+ __not_<is_same<__remove_cvref_t<_Sseq>, _Engine>>,
+ is_unsigned<typename _Sseq::result_type>,
+ __not_<is_convertible<_Sseq, _Res>>
+ >;
+
} // namespace __detail
I'm considering backporting this, with a simpler constraint:
// Detect whether _Sseq is a valid seed sequence for
// a random number engine _Engine with result type _Res.
template<typename _Sseq, typename _Engine, typename _Res>
using __is_seed_seq = __and_< __not_<is_same<_Sseq, _Engine>>,
is_class<_Sseq>,
__not_<is_convertible<_Sseq, _Res>> >;
The rest of the patch would remain the same, so the member functions
would still be constrained by __is_seed_seq but that wouldn't check
for a usable generate function, or nested result_type.
That would still be an improvement on what we have in the branches
today, where the constructors taking a _Sseq are minimally-constrained
and the seed(_Sseq&) functions are constrained on !is_class<_Sseq>.