[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