[PATCH] PR libstdc++/85749 constrain seed sequences for random number engines
Jonathan Wakely
jwakely@redhat.com
Tue May 15 16:41:00 GMT 2018
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 <jwakely@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>.
More information about the Libstdc++
mailing list