]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR libstdc++/42408 (Missing templatized seed())
authorPaolo Carlini <paolo.carlini@oracle.com>
Mon, 1 Feb 2010 19:45:23 +0000 (19:45 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Mon, 1 Feb 2010 19:45:23 +0000 (19:45 +0000)
2010-02-01  Paolo Carlini  <paolo.carlini@oracle.com>

PR libstdc++/42408
* include/bits/random.h (linear_congruential_engine<>::
linear_congruential_engine(seed_seq&),
linear_congruential_engine<>::seed(seed_seq&),
mersenne_twister<>::mersenne_twister(seed_seq&),
mersenne_twister<>::seed(seed_seq&),
subtract_with_carry_engine<>::subtract_with_carry_engine(seed_seq&),
subtract_with_carry_engine<>::seed(seed_seq&),
discard_block_engine<>::discard_block_engine(seed_seq&),
discard_block_engine<>::seed(seed_seq&),
independent_bits_engine<>::independent_bits_engine(seed_seq&),
independent_bits_engine<>::seed(seed_seq&),
shuffle_order_engine<>::shuffle_order_engine(seed_seq&),
shuffle_order_engine<>::seed(seed_seq&)): Templatize.
* include/bits/random.tcc: Adjust.
* testsuite/26_numerics/random/subtract_with_carry_engine/cons/
seed_seq.cc: New.
* testsuite/26_numerics/random/mersenne_twister_engine/cons/
seed_seq.cc: Likewise.
* testsuite/26_numerics/random/linear_congruential_engine/
cons/seed_seq.cc: Likewise.

From-SVN: r156430

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/random.h
libstdc++-v3/include/bits/random.tcc
libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed_seq.cc [new file with mode: 0644]
libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed_seq.cc [new file with mode: 0644]
libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed_seq.cc [new file with mode: 0644]

index a3e0a4249639335b9bb02196cd797894150323ce..2e9e849a2dbf0e004209be22988ed8513e5d32d9 100644 (file)
@@ -1,3 +1,27 @@
+2010-02-01  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR libstdc++/42408
+       * include/bits/random.h (linear_congruential_engine<>::
+       linear_congruential_engine(seed_seq&),
+       linear_congruential_engine<>::seed(seed_seq&),
+       mersenne_twister<>::mersenne_twister(seed_seq&),
+       mersenne_twister<>::seed(seed_seq&),
+       subtract_with_carry_engine<>::subtract_with_carry_engine(seed_seq&),
+       subtract_with_carry_engine<>::seed(seed_seq&),
+       discard_block_engine<>::discard_block_engine(seed_seq&),
+       discard_block_engine<>::seed(seed_seq&),
+       independent_bits_engine<>::independent_bits_engine(seed_seq&),
+       independent_bits_engine<>::seed(seed_seq&),
+       shuffle_order_engine<>::shuffle_order_engine(seed_seq&),
+       shuffle_order_engine<>::seed(seed_seq&)): Templatize.
+       * include/bits/random.tcc: Adjust.
+       * testsuite/26_numerics/random/subtract_with_carry_engine/cons/
+       seed_seq.cc: New.
+       * testsuite/26_numerics/random/mersenne_twister_engine/cons/
+       seed_seq.cc: Likewise.
+       * testsuite/26_numerics/random/linear_congruential_engine/
+       cons/seed_seq.cc: Likewise.
+
 2010-02-01  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * include/bits/forward_list.h (forward_list<>::resize(size_type),
index c86eb9947f84520adeca078179b2a17c8dae62d5..528a04a091185e73aab243ca72c630be3361800c 100644 (file)
@@ -1,6 +1,6 @@
 // random number generation -*- C++ -*-
 
-// Copyright (C) 2009 Free Software Foundation, Inc.
+// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -50,8 +50,6 @@ namespace std
     _RealType
     generate_canonical(_UniformRandomNumberGenerator& __g);
 
-  class seed_seq;
-
   /*
    * Implementation-space details.
    */
@@ -179,7 +177,7 @@ namespace std
        */
       explicit
       linear_congruential_engine(result_type __s = default_seed)
-      { this->seed(__s); }
+      { seed(__s); }
 
       /**
        * @brief Constructs a %linear_congruential_engine random number
@@ -187,9 +185,11 @@ namespace std
        *
        * @param __q the seed sequence.
        */
-      explicit
-      linear_congruential_engine(seed_seq& __q)
-      { this->seed(__q); }
+      template<typename _Sseq, typename
+              = typename std::enable_if<std::is_class<_Sseq>::value>::type>
+        explicit
+        linear_congruential_engine(_Sseq& __q)
+        { seed<_Sseq>(__q); }
 
       /**
        * @brief Reseeds the %linear_congruential_engine random number generator
@@ -207,8 +207,10 @@ namespace std
        *
        * @param __q the seed sequence.
        */
-      void
-      seed(seed_seq& __q);
+      template<typename _Sseq, typename
+              = typename std::enable_if<std::is_class<_Sseq>::value>::type>
+        void
+        seed(_Sseq& __q);
 
       /**
        * @brief Gets the smallest possible value in the output range.
@@ -398,15 +400,19 @@ namespace std
        *
        * @param __q the seed sequence.
        */
-      explicit
-      mersenne_twister_engine(seed_seq& __q)
-      { seed(__q); }
+      template<typename _Sseq, typename
+              = typename std::enable_if<std::is_class<_Sseq>::value>::type>
+        explicit
+        mersenne_twister_engine(_Sseq& __q)
+        { seed<_Sseq>(__q); }
 
       void
       seed(result_type __sd = default_seed);
 
-      void
-      seed(seed_seq& __q);
+      template<typename _Sseq, typename
+              = typename std::enable_if<std::is_class<_Sseq>::value>::type>
+        void
+        seed(_Sseq& __q);
 
       /**
        * @brief Gets the smallest possible value in the output range.
@@ -557,7 +563,7 @@ namespace std
        */
       explicit
       subtract_with_carry_engine(result_type __sd = default_seed)
-      { this->seed(__sd); }
+      { seed(__sd); }
 
       /**
        * @brief Constructs a %subtract_with_carry_engine random number engine
@@ -565,9 +571,11 @@ namespace std
        *
        * @param __q the seed sequence.
        */
-      explicit
-      subtract_with_carry_engine(seed_seq& __q)
-      { this->seed(__q); }
+      template<typename _Sseq, typename
+              = typename std::enable_if<std::is_class<_Sseq>::value>::type>
+        explicit
+        subtract_with_carry_engine(_Sseq& __q)
+        { seed<_Sseq>(__q); }
 
       /**
        * @brief Seeds the initial state @f$ x_0 @f$ of the random number
@@ -588,8 +596,10 @@ namespace std
        * @brief Seeds the initial state @f$ x_0 @f$ of the
        * % subtract_with_carry_engine random number generator.
        */
-      void
-      seed(seed_seq& __q);
+      template<typename _Sseq, typename
+              = typename std::enable_if<std::is_class<_Sseq>::value>::type>
+        void
+        seed(_Sseq& __q);
 
       /**
        * @brief Gets the inclusive minimum value of the range of random
@@ -670,7 +680,8 @@ namespace std
        *        @p __is.
        *
        * @param __is An input stream.
-       * @param __x  A % subtract_with_carry_engine random number generator engine.
+       * @param __x  A % subtract_with_carry_engine random number generator
+       *             engine.
        *
        * @returns The input stream with the state of @p __x extracted or in
        * an error state.
@@ -751,10 +762,14 @@ namespace std
        *
        * @param __q A seed sequence.
        */
-      explicit
-      discard_block_engine(seed_seq& __q)
-      : _M_b(__q), _M_n(0)
-      { }
+      template<typename _Sseq, typename
+        = typename std::enable_if<std::is_class<_Sseq>::value
+                                 && !std::is_same<_Sseq, _RandomNumberEngine>
+                                 ::value>::type>
+        explicit
+        discard_block_engine(_Sseq& __q)
+       : _M_b(__q), _M_n(0)
+        { }
 
       /**
        * @brief Reseeds the %discard_block_engine object with the default
@@ -783,12 +798,14 @@ namespace std
        *        sequence.
        * @param __q A seed generator function.
        */
-      void
-      seed(seed_seq& __q)
-      {
-        _M_b.seed(__q);
-        _M_n = 0;
-      }
+      template<typename _Sseq, typename
+              = typename std::enable_if<std::is_class<_Sseq>::value>::type>
+        void
+        seed(_Sseq& __q)
+        {
+         _M_b.seed<_Sseq>(__q);
+         _M_n = 0;
+       }
 
       /**
        * @brief Gets a const reference to the underlying generator engine
@@ -949,10 +966,14 @@ namespace std
        *
        * @param __q A seed sequence.
        */
-      explicit
-      independent_bits_engine(seed_seq& __q)
-      : _M_b(__q)
-      { }
+      template<typename _Sseq, typename
+        = typename std::enable_if<std::is_class<_Sseq>::value
+                                 && !std::is_same<_Sseq, _RandomNumberEngine>
+                                 ::value>::type>
+        explicit
+        independent_bits_engine(_Sseq& __q)
+        : _M_b(__q)
+        { }
 
       /**
        * @brief Reseeds the %independent_bits_engine object with the default
@@ -975,9 +996,11 @@ namespace std
        *        seed sequence.
        * @param __q A seed generator function.
        */
-      void
-      seed(seed_seq& __q)
-      { _M_b.seed(__q); }
+      template<typename _Sseq, typename
+              = typename std::enable_if<std::is_class<_Sseq>::value>::type>
+        void
+        seed(_Sseq& __q)
+        { _M_b.seed<_Sseq>(__q); }
 
       /**
        * @brief Gets a const reference to the underlying generator engine
@@ -1150,10 +1173,14 @@ namespace std
        *
        * @param __q A seed sequence.
        */
-      explicit
-      shuffle_order_engine(seed_seq& __q)
-      : _M_b(__q)
-      { _M_initialize(); }
+      template<typename _Sseq, typename
+        = typename std::enable_if<std::is_class<_Sseq>::value
+                                 && !std::is_same<_Sseq, _RandomNumberEngine>
+                                 ::value>::type>
+        explicit
+        shuffle_order_engine(_Sseq& __q)
+        : _M_b(__q)
+        { _M_initialize(); }
 
       /**
        * @brief Reseeds the %shuffle_order_engine object with the default seed
@@ -1182,12 +1209,14 @@ namespace std
        *        sequence.
        * @param __q A seed generator function.
        */
-      void
-      seed(seed_seq& __q)
-      {
-        _M_b.seed(__q);
-        _M_initialize();
-      }
+      template<typename _Sseq, typename
+              = typename std::enable_if<std::is_class<_Sseq>::value>::type>
+        void
+        seed(_Sseq& __q)
+        {
+         _M_b.seed<_Sseq>(__q);
+         _M_initialize();
+       }
 
       /**
        * Gets a const reference to the underlying generator engine object.
index 712426ec9b6475a95f0192facac197ff6f5157fd..4a8c4d86f710210a5218a09543b018ae08442ae4 100644 (file)
@@ -1,6 +1,6 @@
 // random number generation (out of line) -*- C++ -*-
 
-// Copyright (C) 2009 Free Software Foundation, Inc.
+// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -126,24 +126,25 @@ namespace std
    * Seeds the LCR engine with a value generated by @p __q.
    */
   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
-    void
-    linear_congruential_engine<_UIntType, __a, __c, __m>::
-    seed(seed_seq& __q)
-    {
-      const _UIntType __k0 = __m == 0 ? std::numeric_limits<_UIntType>::digits
-                                     : std::__lg(__m);
-      const _UIntType __k = (__k0 + 31) / 32;
-      uint_least32_t __arr[__k + 3];
-      __q.generate(__arr + 0, __arr + __k + 3);
-      _UIntType __factor = 1u;
-      _UIntType __sum = 0u;
-      for (size_t __j = 0; __j < __k; ++__j)
-        {
-          __sum += __arr[__j + 3] * __factor;
-          __factor *= __detail::_Shift<_UIntType, 32>::__value;
-        }
-      seed(__sum);
-    }
+    template<typename _Sseq, typename>
+      void
+      linear_congruential_engine<_UIntType, __a, __c, __m>::
+      seed(_Sseq& __q)
+      {
+       const _UIntType __k0 = __m == 0 ? std::numeric_limits<_UIntType>::digits
+                                       : std::__lg(__m);
+       const _UIntType __k = (__k0 + 31) / 32;
+       uint_least32_t __arr[__k + 3];
+       __q.generate(__arr + 0, __arr + __k + 3);
+       _UIntType __factor = 1u;
+       _UIntType __sum = 0u;
+       for (size_t __j = 0; __j < __k; ++__j)
+         {
+           __sum += __arr[__j + 3] * __factor;
+           __factor *= __detail::_Shift<_UIntType, 32>::__value;
+         }
+       seed(__sum);
+      }
 
   template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
           typename _CharT, typename _Traits>
@@ -343,43 +344,44 @@ namespace std
           _UIntType __a, size_t __u, _UIntType __d, size_t __s,
           _UIntType __b, size_t __t, _UIntType __c, size_t __l,
           _UIntType __f>
-    void
-    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
+    template<typename _Sseq, typename>
+      void
+      mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
                              __s, __b, __t, __c, __l, __f>::
-    seed(seed_seq& __q)
-    {
-      const _UIntType __upper_mask = (~_UIntType()) << __r;
-      const size_t __k = (__w + 31) / 32;
-      uint_least32_t __arr[__n * __k];
-      __q.generate(__arr + 0, __arr + __n * __k);
-
-      bool __zero = true;
-      for (size_t __i = 0; __i < state_size; ++__i)
-        {
-          _UIntType __factor = 1u;
-          _UIntType __sum = 0u;
-          for (size_t __j = 0; __j < __k; ++__j)
-            {
-             __sum += __arr[__k * __i + __j] * __factor;
-             __factor *= __detail::_Shift<_UIntType, 32>::__value;
-            }
-          _M_x[__i] = __detail::__mod<_UIntType,
-           __detail::_Shift<_UIntType, __w>::__value>(__sum);
+      seed(_Sseq& __q)
+      {
+       const _UIntType __upper_mask = (~_UIntType()) << __r;
+       const size_t __k = (__w + 31) / 32;
+       uint_least32_t __arr[__n * __k];
+       __q.generate(__arr + 0, __arr + __n * __k);
+
+       bool __zero = true;
+       for (size_t __i = 0; __i < state_size; ++__i)
+         {
+           _UIntType __factor = 1u;
+           _UIntType __sum = 0u;
+           for (size_t __j = 0; __j < __k; ++__j)
+             {
+               __sum += __arr[__k * __i + __j] * __factor;
+               __factor *= __detail::_Shift<_UIntType, 32>::__value;
+             }
+           _M_x[__i] = __detail::__mod<_UIntType,
+             __detail::_Shift<_UIntType, __w>::__value>(__sum);
 
-          if (__zero)
-            {
-             if (__i == 0)
-               {
-                 if ((_M_x[0] & __upper_mask) != 0u)
-                   __zero = false;
-               }
-             else if (_M_x[__i] != 0u)
-               __zero = false;
-            }
-        }
+           if (__zero)
+             {
+               if (__i == 0)
+                 {
+                   if ((_M_x[0] & __upper_mask) != 0u)
+                     __zero = false;
+                 }
+               else if (_M_x[__i] != 0u)
+                 __zero = false;
+             }
+         }
         if (__zero)
           _M_x[0] = __detail::_Shift<_UIntType, __w - 1>::__value;
-    }
+      }
 
   template<typename _UIntType, size_t __w,
           size_t __n, size_t __m, size_t __r,
@@ -529,29 +531,30 @@ namespace std
     }
 
   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
-    void
-    subtract_with_carry_engine<_UIntType, __w, __s, __r>::
-    seed(seed_seq& __q)
-    {
-      const size_t __k = (__w + 31) / 32;
-      uint_least32_t __arr[__r * __k];
-      __q.generate(__arr + 0, __arr + __r * __k);
+    template<typename _Sseq, typename>
+      void
+      subtract_with_carry_engine<_UIntType, __w, __s, __r>::
+      seed(_Sseq& __q)
+      {
+       const size_t __k = (__w + 31) / 32;
+       uint_least32_t __arr[__r * __k];
+       __q.generate(__arr + 0, __arr + __r * __k);
 
-      for (size_t __i = 0; __i < long_lag; ++__i)
-        {
-          _UIntType __sum = 0u;
-          _UIntType __factor = 1u;
-          for (size_t __j = 0; __j < __k; ++__j)
-            {
-             __sum += __arr[__k * __i + __j] * __factor;
-             __factor *= __detail::_Shift<_UIntType, 32>::__value;
-            }
-          _M_x[__i] = __detail::__mod<_UIntType,
-           __detail::_Shift<_UIntType, __w>::__value>(__sum);
-        }
-      _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
-      _M_p = 0;
-    }
+       for (size_t __i = 0; __i < long_lag; ++__i)
+         {
+           _UIntType __sum = 0u;
+           _UIntType __factor = 1u;
+           for (size_t __j = 0; __j < __k; ++__j)
+             {
+               __sum += __arr[__k * __i + __j] * __factor;
+               __factor *= __detail::_Shift<_UIntType, 32>::__value;
+             }
+           _M_x[__i] = __detail::__mod<_UIntType,
+             __detail::_Shift<_UIntType, __w>::__value>(__sum);
+         }
+       _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0;
+       _M_p = 0;
+      }
 
   template<typename _UIntType, size_t __w, size_t __s, size_t __r>
     typename subtract_with_carry_engine<_UIntType, __w, __s, __r>::
diff --git a/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed_seq.cc b/libstdc++-v3/testsuite/26_numerics/random/linear_congruential_engine/cons/seed_seq.cc
new file mode 100644 (file)
index 0000000..4ec39b5
--- /dev/null
@@ -0,0 +1,39 @@
+// { dg-options "-std=c++0x" }
+// { dg-require-cstdint "" }
+//
+// 2010-02-01  Paolo Carlini  <paolo.carlini@oracle.com>
+//
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 26.4.3.1 class template linear_congruential_engine [rand.eng.lcong]
+// 26.4.2.2 Concept RandomNumberEngine [rand.concept.eng]
+
+#include <random>
+
+void
+test01()
+{
+  std::seed_seq seed;
+  std::linear_congruential_engine<unsigned long, 48271, 0, 2147483647> x(seed);
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed_seq.cc b/libstdc++-v3/testsuite/26_numerics/random/mersenne_twister_engine/cons/seed_seq.cc
new file mode 100644 (file)
index 0000000..c2fb913
--- /dev/null
@@ -0,0 +1,44 @@
+// { dg-options "-std=c++0x" }
+// { dg-require-cstdint "" }
+//
+// 2010-02-01  Paolo Carlini  <paolo.carlini@oracle.com>
+//
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 26.4.3.2 Class template mersenne_twister_engine [rand.eng.mers]
+// 26.4.2.2 Concept RandomNumberEngine [rand.concept.eng]
+
+#include <random>
+
+void
+test01()
+{
+  std::seed_seq seed;
+  std::mersenne_twister_engine<
+    unsigned long, 32, 624, 397, 31,
+    0x9908b0dful, 11,
+    0xfffffffful, 7,
+    0x9d2c5680ul, 15,
+    0xefc60000ul, 18, 1812433253ul> x(seed);
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed_seq.cc b/libstdc++-v3/testsuite/26_numerics/random/subtract_with_carry_engine/cons/seed_seq.cc
new file mode 100644 (file)
index 0000000..617c455
--- /dev/null
@@ -0,0 +1,39 @@
+// { dg-options "-std=c++0x" }
+// { dg-require-cstdint "" }
+//
+// 2010-02-01  Paolo Carlini  <paolo.carlini@oracle.com>
+//
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 26.4.3.3 Class template subtract_with_carry_engine [rand.eng.sub]
+// 26.4.2.2 Concept RandomNumberEngine [rand.concept.eng]
+
+#include <random>
+
+void
+test01()
+{
+  std::seed_seq seed;
+  std::subtract_with_carry_engine<unsigned long, 24, 10, 24> x(seed);
+}
+
+int main()
+{
+  test01();
+  return 0;
+}