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>.

Reply via email to