This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] libstdc++/69240 generic operator!= for random number distributions


How do people feel about this approach to solving PR 69240?

The bug is that we don't define operator!= for RND::param_type, where
RND is any of random number distributions in <random> or <ext/random>.
Rather than tediously defining it for every param_type I've added
this:

 namespace __random_not_eq
 {
   // Derive from this tag to define l != r as !(l == r).
   struct __tag { };

   /// Compare the parameters of two random number distributions.
   template<typename _Tp>
     inline bool
     operator!=(const _Tp& __lhs, const _Tp& __rhs) noexcept
     { return !(__lhs == __rhs); }
 }

Then made the param types derive from the tag:

     /** Parameter type. */
     struct param_type : private __random_not_eq::__tag

This makes std::__random_not_eq an associated namespace of the
param_type, and so the generic operator!= is found by ADL, solving the
bug with a single operator!= function template.

There's no requirement that operator!= be defined for each param_type,
or be visible in namespace std. All that's required is that the types
are comparable with == and != and with this technique that works,
thanks to the magic of ADL.

We can also use __random_not_eq::__tag for the distributions
themselves, allowing us remove the operator!= overloads defined for
every distribution type:

 template<typename _RealType = double>
   class normal_distribution : private __random_not_eq::__tag

I've then taken the idea one step further and defined a generic
operator== as well:

 namespace __random_eq
 {
   // Derive from this tag to define l == r as l.param() == r.param()
   // and l != r as !(l == r).
   struct __tag { };

   /// Compare the parameters of two random number distributions.
   template<typename _Tp>
     inline bool
     operator==(const _Tp& __lhs, const _Tp& __rhs) noexcept
     { return __lhs.param() == __rhs.param(); }
 }

This can be used by any distribution for which equality is defined
simply in terms of parameter equality, allowing us to remove 14 boring
operator== overloads that just do __d1._M_param == __d2._M_param.

If this approach looks worringly like std::rel_ops then fear not. This
way of doing it is much safer, because the generic operators are never
brought into namespace std (or any other namespace) with "using". They
can only be found by ADL by making __random_not_eq and/or __random_eq
an associated namespace.

This patch is missing tests so isn't ready to commit, but I want to
know if anyone will freak out at this use of ADL. I think fixing a bug
in dozens of classes while *removing* hundreds of lines of code is
pretty cool.

commit 9ad214ebd024872fddb490eb4349ec8055bfc41a
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Jan 14 18:59:29 2016 +0000

    Define tag types for enable (in)equality operators via ADL
    
    	PR libstdc++/69240
    	* include/bits/random.h (__random_not_eq::__tag, __random_eq::__tag):
    	Define tag types for enabling generic equality/inequality operators via
    	ADL.
    	(uniform_int_distribution, uniform_real_distribution,
    	normal_distribution, lognormal_distribution, chi_squared_distribution,
    	cauchy_distribution, fisher_f_distribution, student_t_distribution,
    	bernoulli_distribution, binomial_distribution, geometric_distribution,
    	negative_binomial_distribution, poisson_distribution,
    	exponential_distribution, weibull_distribution,
    	extreme_value_distribution, discrete_distribution,
    	piecewise_constant_distribution, piecewise_linear_distribution): Derive
    	from tag types and remove overloaded equality and/or inequality
    	operators.
    	* include/ext/random (beta_distribution, normal_mv_distribution,
    	rice_distribution, nakagami_distribution, pareto_distribution,
    	k_distribution, arcsine_distribution, hoyt_distribution,
    	triangular_distribution,  von_mises_distribution,
    	hypergeometric_distribution, logistic_distribution,
    	uniform_on_sphere_distribution): Likewise.

diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h
index 63f57d5..6ff27d6 100644
--- a/libstdc++-v3/include/bits/random.h
+++ b/libstdc++-v3/include/bits/random.h
@@ -1656,13 +1656,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * @{
    */
 
+  namespace __random_not_eq
+  {
+    // Derive from this tag to define l != r as !(l == r).
+    struct __tag { };
+
+    /// Compare the parameters of two random number distributions.
+    template<typename _Tp>
+      inline bool
+      operator!=(const _Tp& __lhs, const _Tp& __rhs) noexcept
+      { return !(__lhs == __rhs); }
+  }
+
+  namespace __random_eq
+  {
+    // Derive from this tag to define l == r as l.param() == r.param()
+    // and l != r as !(l == r).
+    struct __tag : __random_not_eq::__tag { };
+
+    /// Compare the parameters of two random number distributions.
+    template<typename _Tp>
+      inline bool
+      operator==(const _Tp& __lhs, const _Tp& __rhs) noexcept
+      { return __lhs.param() == __rhs.param(); }
+  }
+
   /**
    * @brief Uniform discrete distribution for random numbers.
    * A discrete random distribution on the range @f$[min, max]@f$ with equal
    * probability throughout the range.
    */
   template<typename _IntType = int>
-    class uniform_int_distribution
+    class uniform_int_distribution : private __random_eq::__tag
     {
       static_assert(std::is_integral<_IntType>::value,
 		    "template argument not an integral type");
@@ -1670,14 +1695,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _IntType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef uniform_int_distribution<_IntType> distribution_type;
 
 	explicit
 	param_type(_IntType __a = 0,
-		   _IntType __b = std::numeric_limits<_IntType>::max())
+		   _IntType __b = numeric_limits<_IntType>::max())
 	: _M_a(__a), _M_b(__b)
 	{
 	  __glibcxx_assert(_M_a <= _M_b);
@@ -1706,7 +1732,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        */
       explicit
       uniform_int_distribution(_IntType __a = 0,
-			   _IntType __b = std::numeric_limits<_IntType>::max())
+			       _IntType __b = numeric_limits<_IntType>::max())
       : _M_param(__a, __b)
       { }
 
@@ -1795,15 +1821,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		   const param_type& __p)
 	{ this->__generate_impl(__f, __t, __urng, __p); }
 
-      /**
-       * @brief Return true if two uniform integer distributions have
-       *        the same parameters.
-       */
-      friend bool
-      operator==(const uniform_int_distribution& __d1,
-		 const uniform_int_distribution& __d2)
-      { return __d1._M_param == __d2._M_param; }
-
     private:
       template<typename _ForwardIterator,
 	       typename _UniformRandomNumberGenerator>
@@ -1816,16 +1833,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   /**
-   * @brief Return true if two uniform integer distributions have
-   *        different parameters.
-   */
-  template<typename _IntType>
-    inline bool
-    operator!=(const std::uniform_int_distribution<_IntType>& __d1,
-	       const std::uniform_int_distribution<_IntType>& __d2)
-    { return !(__d1 == __d2); }
-
-  /**
    * @brief Inserts a %uniform_int_distribution random number
    *        distribution @p __x into the output stream @p os.
    *
@@ -1863,7 +1870,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * deliver number in the range [0, 1).
    */
   template<typename _RealType = double>
-    class uniform_real_distribution
+    class uniform_real_distribution : private __random_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -1871,8 +1878,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef uniform_real_distribution<_RealType> distribution_type;
 
@@ -2004,15 +2012,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		   const param_type& __p)
 	{ this->__generate_impl(__f, __t, __urng, __p); }
 
-      /**
-       * @brief Return true if two uniform real distributions have
-       *        the same parameters.
-       */
-      friend bool
-      operator==(const uniform_real_distribution& __d1,
-		 const uniform_real_distribution& __d2)
-      { return __d1._M_param == __d2._M_param; }
-
     private:
       template<typename _ForwardIterator,
 	       typename _UniformRandomNumberGenerator>
@@ -2025,16 +2024,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   /**
-   * @brief Return true if two uniform real distributions have
-   *        different parameters.
-   */
-  template<typename _IntType>
-    inline bool
-    operator!=(const std::uniform_real_distribution<_IntType>& __d1,
-	       const std::uniform_real_distribution<_IntType>& __d2)
-    { return !(__d1 == __d2); }
-
-  /**
    * @brief Inserts a %uniform_real_distribution random number
    *        distribution @p __x into the output stream @p __os.
    *
@@ -2081,7 +2070,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * @f]
    */
   template<typename _RealType = double>
-    class normal_distribution
+    class normal_distribution : private __random_not_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -2089,8 +2078,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef normal_distribution<_RealType> distribution_type;
 
@@ -2228,7 +2218,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        */
       template<typename _RealType1>
 	friend bool
-        operator==(const std::normal_distribution<_RealType1>& __d1,
+	operator==(const std::normal_distribution<_RealType1>& __d1,
 		   const std::normal_distribution<_RealType1>& __d2);
 
       /**
@@ -2275,16 +2265,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   /**
-   * @brief Return true if two normal distributions are different.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const std::normal_distribution<_RealType>& __d1,
-	       const std::normal_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
-
-  /**
    * @brief A lognormal_distribution random number distribution.
    *
    * The formula for the normal probability mass function is
@@ -2294,7 +2274,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * @f]
    */
   template<typename _RealType = double>
-    class lognormal_distribution
+    class lognormal_distribution : private __random_not_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -2302,8 +2282,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef lognormal_distribution<_RealType> distribution_type;
 
@@ -2479,16 +2460,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   /**
-   * @brief Return true if two lognormal distributions are different.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const std::lognormal_distribution<_RealType>& __d1,
-	       const std::lognormal_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
-
-  /**
    * @brief A gamma continuous distribution for random numbers.
    *
    * The formula for the gamma probability density function is:
@@ -2498,7 +2469,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * @f]
    */
   template<typename _RealType = double>
-    class gamma_distribution
+    class gamma_distribution : private __random_not_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -2506,8 +2477,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef gamma_distribution<_RealType> distribution_type;
 	friend class gamma_distribution<_RealType>;
@@ -2698,15 +2670,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       std::normal_distribution<result_type> _M_nd;
     };
 
-  /**
-   * @brief Return true if two gamma distributions are different.
-   */
-   template<typename _RealType>
-     inline bool
-     operator!=(const std::gamma_distribution<_RealType>& __d1,
-		const std::gamma_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
 
   /**
    * @brief A chi_squared_distribution random number distribution.
@@ -2715,7 +2678,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * @f$p(x|n) = \frac{x^{(n/2) - 1}e^{-x/2}}{\Gamma(n/2) 2^{n/2}}@f$
    */
   template<typename _RealType = double>
-    class chi_squared_distribution
+    class chi_squared_distribution : private __random_not_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -2723,8 +2686,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef chi_squared_distribution<_RealType> distribution_type;
 
@@ -2909,23 +2873,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   /**
-   * @brief Return true if two Chi-squared distributions are different.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const std::chi_squared_distribution<_RealType>& __d1,
-	       const std::chi_squared_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
-
-  /**
    * @brief A cauchy_distribution random number distribution.
    *
    * The formula for the normal probability mass function is
    * @f$p(x|a,b) = (\pi b (1 + (\frac{x-a}{b})^2))^{-1}@f$
    */
   template<typename _RealType = double>
-    class cauchy_distribution
+    class cauchy_distribution : private __random_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -2933,8 +2887,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef cauchy_distribution<_RealType> distribution_type;
 
@@ -3075,16 +3030,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   /**
-   * @brief Return true if two Cauchy distributions have
-   *        different parameters.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const std::cauchy_distribution<_RealType>& __d1,
-	       const std::cauchy_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
-  /**
    * @brief Inserts a %cauchy_distribution random number distribution
    * @p __x into the output stream @p __os.
    *
@@ -3126,7 +3071,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * @f]
    */
   template<typename _RealType = double>
-    class fisher_f_distribution
+    class fisher_f_distribution : private __random_not_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -3134,8 +3079,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef fisher_f_distribution<_RealType> distribution_type;
 
@@ -3332,15 +3278,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   /**
-   * @brief Return true if two Fisher f distributions are different.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const std::fisher_f_distribution<_RealType>& __d1,
-	       const std::fisher_f_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
-  /**
    * @brief A student_t_distribution random number distribution.
    *
    * The formula for the normal probability mass function is:
@@ -3350,7 +3287,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * @f]
    */
   template<typename _RealType = double>
-    class student_t_distribution
+    class student_t_distribution : private __random_not_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -3358,8 +3295,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef student_t_distribution<_RealType> distribution_type;
 
@@ -3544,16 +3482,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       std::gamma_distribution<result_type> _M_gd;
     };
 
-  /**
-   * @brief Return true if two Student t distributions are different.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const std::student_t_distribution<_RealType>& __d1,
-	       const std::student_t_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
-
   /* @} */ // group random_distributions_normal
 
   /**
@@ -3568,13 +3496,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * Generates a sequence of true and false values with likelihood @f$p@f$
    * that true will come up and @f$(1 - p)@f$ that false will appear.
    */
-  class bernoulli_distribution
+  class bernoulli_distribution : private __random_eq::__tag
   {
   public:
     /** The type of the range of the distribution. */
     typedef bool result_type;
+
     /** Parameter type. */
-    struct param_type
+    struct param_type : private __random_not_eq::__tag
     {
       typedef bernoulli_distribution distribution_type;
 
@@ -3721,15 +3650,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   };
 
   /**
-   * @brief Return true if two Bernoulli distributions have
-   *        different parameters.
-   */
-  inline bool
-  operator!=(const std::bernoulli_distribution& __d1,
-	     const std::bernoulli_distribution& __d2)
-  { return !(__d1 == __d2); }
-
-  /**
    * @brief Inserts a %bernoulli_distribution random number distribution
    * @p __x into the output stream @p __os.
    *
@@ -3773,7 +3693,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * and @f$p@f$ are the parameters of the distribution.
    */
   template<typename _IntType = int>
-    class binomial_distribution
+    class binomial_distribution : private __random_not_eq::__tag
     {
       static_assert(std::is_integral<_IntType>::value,
 		    "template argument not an integral type");
@@ -3781,8 +3701,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _IntType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef binomial_distribution<_IntType> distribution_type;
 	friend class binomial_distribution<_IntType>;
@@ -3986,15 +3907,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       std::normal_distribution<double> _M_nd;
     };
 
-  /**
-   * @brief Return true if two binomial distributions are different.
-   */
-  template<typename _IntType>
-    inline bool
-    operator!=(const std::binomial_distribution<_IntType>& __d1,
-	       const std::binomial_distribution<_IntType>& __d2)
-    { return !(__d1 == __d2); }
-
 
   /**
    * @brief A discrete geometric random number distribution.
@@ -4004,7 +3916,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * distribution.
    */
   template<typename _IntType = int>
-    class geometric_distribution
+    class geometric_distribution : private __random_eq::__tag
     {
       static_assert(std::is_integral<_IntType>::value,
 		    "template argument not an integral type");
@@ -4012,8 +3924,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _IntType  result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef geometric_distribution<_IntType> distribution_type;
 	friend class geometric_distribution<_IntType>;
@@ -4134,15 +4047,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		   const param_type& __p)
 	{ this->__generate_impl(__f, __t, __urng, __p); }
 
-      /**
-       * @brief Return true if two geometric distributions have
-       *        the same parameters.
-       */
-      friend bool
-      operator==(const geometric_distribution& __d1,
-		 const geometric_distribution& __d2)
-      { return __d1._M_param == __d2._M_param; }
-
     private:
       template<typename _ForwardIterator,
 	       typename _UniformRandomNumberGenerator>
@@ -4204,7 +4108,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * and @f$p@f$ are the parameters of the distribution.
    */
   template<typename _IntType = int>
-    class negative_binomial_distribution
+    class negative_binomial_distribution : private __random_not_eq::__tag
     {
       static_assert(std::is_integral<_IntType>::value,
 		    "template argument not an integral type");
@@ -4212,8 +4116,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _IntType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef negative_binomial_distribution<_IntType> distribution_type;
 
@@ -4400,16 +4305,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       std::gamma_distribution<double> _M_gd;
     };
 
-  /**
-   * @brief Return true if two negative binomial distributions are different.
-   */
-  template<typename _IntType>
-    inline bool
-    operator!=(const std::negative_binomial_distribution<_IntType>& __d1,
-	       const std::negative_binomial_distribution<_IntType>& __d2)
-    { return !(__d1 == __d2); }
-
-
   /* @} */ // group random_distributions_bernoulli
 
   /**
@@ -4426,7 +4321,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * parameter of the distribution.
    */
   template<typename _IntType = int>
-    class poisson_distribution
+    class poisson_distribution : private __random_not_eq::__tag
     {
       static_assert(std::is_integral<_IntType>::value,
 		    "template argument not an integral type");
@@ -4434,8 +4329,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _IntType  result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef poisson_distribution<_IntType> distribution_type;
 	friend class poisson_distribution<_IntType>;
@@ -4617,16 +4513,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   /**
-   * @brief Return true if two Poisson distributions are different.
-   */
-  template<typename _IntType>
-    inline bool
-    operator!=(const std::poisson_distribution<_IntType>& __d1,
-	       const std::poisson_distribution<_IntType>& __d2)
-    { return !(__d1 == __d2); }
-
-
-  /**
    * @brief An exponential continuous distribution for random numbers.
    *
    * The formula for the exponential probability density function is
@@ -4642,7 +4528,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * </table>
    */
   template<typename _RealType = double>
-    class exponential_distribution
+    class exponential_distribution : private __random_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -4650,8 +4536,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef exponential_distribution<_RealType> distribution_type;
 
@@ -4773,15 +4660,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		   const param_type& __p)
 	{ this->__generate_impl(__f, __t, __urng, __p); }
 
-      /**
-       * @brief Return true if two exponential distributions have the same
-       *        parameters.
-       */
-      friend bool
-      operator==(const exponential_distribution& __d1,
-		 const exponential_distribution& __d2)
-      { return __d1._M_param == __d2._M_param; }
-
     private:
       template<typename _ForwardIterator,
 	       typename _UniformRandomNumberGenerator>
@@ -4794,16 +4672,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   /**
-   * @brief Return true if two exponential distributions have different
-   *        parameters.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const std::exponential_distribution<_RealType>& __d1,
-	       const std::exponential_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
-  /**
    * @brief Inserts a %exponential_distribution random number distribution
    * @p __x into the output stream @p __os.
    *
@@ -4844,7 +4712,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * @f]
    */
   template<typename _RealType = double>
-    class weibull_distribution
+    class weibull_distribution : private __random_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -4852,8 +4720,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef weibull_distribution<_RealType> distribution_type;
 
@@ -4976,15 +4845,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		   const param_type& __p)
 	{ this->__generate_impl(__f, __t, __urng, __p); }
 
-      /**
-       * @brief Return true if two Weibull distributions have the same
-       *        parameters.
-       */
-      friend bool
-      operator==(const weibull_distribution& __d1,
-		 const weibull_distribution& __d2)
-      { return __d1._M_param == __d2._M_param; }
-
     private:
       template<typename _ForwardIterator,
 	       typename _UniformRandomNumberGenerator>
@@ -4996,16 +4856,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       param_type _M_param;
     };
 
-   /**
-    * @brief Return true if two Weibull distributions have different
-    *        parameters.
-    */
-  template<typename _RealType>
-    inline bool
-    operator!=(const std::weibull_distribution<_RealType>& __d1,
-	       const std::weibull_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
   /**
    * @brief Inserts a %weibull_distribution random number distribution
    * @p __x into the output stream @p __os.
@@ -5047,7 +4897,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * @f]
    */
   template<typename _RealType = double>
-    class extreme_value_distribution
+    class extreme_value_distribution : private __random_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -5055,8 +4905,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef extreme_value_distribution<_RealType> distribution_type;
 
@@ -5179,15 +5030,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		   const param_type& __p)
 	{ this->__generate_impl(__f, __t, __urng, __p); }
 
-      /**
-       * @brief Return true if two extreme value distributions have the same
-       *        parameters.
-       */
-      friend bool
-      operator==(const extreme_value_distribution& __d1,
-		 const extreme_value_distribution& __d2)
-      { return __d1._M_param == __d2._M_param; }
-
     private:
       template<typename _ForwardIterator,
 	       typename _UniformRandomNumberGenerator>
@@ -5200,16 +5042,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   /**
-    * @brief Return true if two extreme value distributions have different
-    *        parameters.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const std::extreme_value_distribution<_RealType>& __d1,
-	       const std::extreme_value_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
-  /**
    * @brief Inserts a %extreme_value_distribution random number distribution
    * @p __x into the output stream @p __os.
    *
@@ -5247,7 +5079,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    *
    */
   template<typename _IntType = int>
-    class discrete_distribution
+    class discrete_distribution : private __random_eq::__tag
     {
       static_assert(std::is_integral<_IntType>::value,
 		    "template argument not an integral type");
@@ -5255,8 +5087,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _IntType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef discrete_distribution<_IntType> distribution_type;
 	friend class discrete_distribution<_IntType>;
@@ -5409,15 +5242,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	{ this->__generate_impl(__f, __t, __urng, __p); }
 
       /**
-       * @brief Return true if two discrete distributions have the same
-       *        parameters.
-       */
-      friend bool
-      operator==(const discrete_distribution& __d1,
-		 const discrete_distribution& __d2)
-      { return __d1._M_param == __d2._M_param; }
-
-      /**
        * @brief Inserts a %discrete_distribution random number distribution
        * @p __x into the output stream @p __os.
        *
@@ -5459,16 +5283,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       param_type _M_param;
     };
 
-  /**
-    * @brief Return true if two discrete distributions have different
-    *        parameters.
-    */
-  template<typename _IntType>
-    inline bool
-    operator!=(const std::discrete_distribution<_IntType>& __d1,
-	       const std::discrete_distribution<_IntType>& __d2)
-    { return !(__d1 == __d2); }
-
 
   /**
    * @brief A piecewise_constant_distribution random number distribution.
@@ -5477,7 +5291,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    *
    */
   template<typename _RealType = double>
-    class piecewise_constant_distribution
+    class piecewise_constant_distribution : private __random_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -5485,8 +5299,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef piecewise_constant_distribution<_RealType> distribution_type;
 	friend class piecewise_constant_distribution<_RealType>;
@@ -5675,15 +5490,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	{ this->__generate_impl(__f, __t, __urng, __p); }
 
       /**
-       * @brief Return true if two piecewise constant distributions have the
-       *        same parameters.
-       */
-      friend bool
-      operator==(const piecewise_constant_distribution& __d1,
-		 const piecewise_constant_distribution& __d2)
-      { return __d1._M_param == __d2._M_param; }
-
-      /**
        * @brief Inserts a %piecewise_constant_distribution random
        *        number distribution @p __x into the output stream @p __os.
        *
@@ -5726,16 +5532,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       param_type _M_param;
     };
 
-  /**
-    * @brief Return true if two piecewise constant distributions have 
-    *        different parameters.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const std::piecewise_constant_distribution<_RealType>& __d1,
-	       const std::piecewise_constant_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
 
   /**
    * @brief A piecewise_linear_distribution random number distribution.
@@ -5744,7 +5540,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    *
    */
   template<typename _RealType = double>
-    class piecewise_linear_distribution
+    class piecewise_linear_distribution : private __random_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -5752,8 +5548,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private __random_not_eq::__tag
       {
 	typedef piecewise_linear_distribution<_RealType> distribution_type;
 	friend class piecewise_linear_distribution<_RealType>;
@@ -5945,15 +5742,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	{ this->__generate_impl(__f, __t, __urng, __p); }
 
       /**
-       * @brief Return true if two piecewise linear distributions have the
-       *        same parameters.
-       */
-      friend bool
-      operator==(const piecewise_linear_distribution& __d1,
-		 const piecewise_linear_distribution& __d2)
-      { return __d1._M_param == __d2._M_param; }
-
-      /**
        * @brief Inserts a %piecewise_linear_distribution random number
        *        distribution @p __x into the output stream @p __os.
        *
@@ -5996,17 +5784,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       param_type _M_param;
     };
 
-  /**
-    * @brief Return true if two piecewise linear distributions have
-    *        different parameters.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const std::piecewise_linear_distribution<_RealType>& __d1,
-	       const std::piecewise_linear_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
-
   /* @} */ // group random_distributions_poisson
 
   /* @} */ // group random_distributions
diff --git a/libstdc++-v3/include/ext/random b/libstdc++-v3/include/ext/random
index cdd3ec1..e09284a 100644
--- a/libstdc++-v3/include/ext/random
+++ b/libstdc++-v3/include/ext/random
@@ -396,7 +396,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * @f]
    */
   template<typename _RealType = double>
-    class beta_distribution
+    class beta_distribution : private std::__random_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -404,8 +404,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private std::__random_not_eq::__tag
       {
 	typedef beta_distribution<_RealType> distribution_type;
 	friend class beta_distribution<_RealType>;
@@ -542,16 +543,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	{ this->__generate_impl(__f, __t, __urng, __p); }
 
       /**
-       * @brief Return true if two beta distributions have the same
-       *        parameters and the sequences that would be generated
-       *        are equal.
-       */
-      friend bool
-      operator==(const beta_distribution& __d1,
-		 const beta_distribution& __d2)
-      { return __d1._M_param == __d2._M_param; }
-
-      /**
        * @brief Inserts a %beta_distribution random number distribution
        * @p __x into the output stream @p __os.
        *
@@ -592,16 +583,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   /**
-   * @brief Return true if two beta distributions are different.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const __gnu_cxx::beta_distribution<_RealType>& __d1,
-	       const __gnu_cxx::beta_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
-
-  /**
    * @brief A multi-variate normal continuous distribution for random numbers.
    *
    * The formula for the normal probability density function is
@@ -617,7 +598,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * matrix (which must be positive-definite).
    */
   template<std::size_t _Dimen, typename _RealType = double>
-    class normal_mv_distribution
+    class normal_mv_distribution : private std::__random_not_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -626,8 +607,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef std::array<_RealType, _Dimen> result_type;
+
       /** Parameter type. */
-      class param_type
+      class param_type : private std::__random_not_eq::__tag
       {
 	static constexpr size_t _M_t_size = _Dimen * (_Dimen + 1) / 2;
 
@@ -899,18 +881,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       std::normal_distribution<_RealType> _M_nd;
   };
 
-  /**
-   * @brief Return true if two multi-variate normal distributions are
-   * different.
-   */
-  template<size_t _Dimen, typename _RealType>
-    inline bool
-    operator!=(const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>&
-	       __d1,
-	       const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>&
-	       __d2)
-    { return !(__d1 == __d2); }
-
 
   /**
    * @brief A Rice continuous distribution for random numbers.
@@ -935,15 +905,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    */
   template<typename _RealType = double>
     class
-    rice_distribution
+    rice_distribution : private std::__random_not_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private std::__random_not_eq::__tag
       {
 	typedef rice_distribution<result_type> distribution_type;
 
@@ -1153,15 +1124,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       std::normal_distribution<result_type> _M_ndy;
     };
 
-  /**
-   * @brief Return true if two Rice distributions are not equal.
-   */
-  template<typename _RealType1>
-    inline bool
-    operator!=(const rice_distribution<_RealType1>& __d1,
-	       const rice_distribution<_RealType1>& __d2)
-    { return !(__d1 == __d2); }
-
 
   /**
    * @brief A Nakagami continuous distribution for random numbers.
@@ -1176,7 +1138,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    */
   template<typename _RealType = double>
     class
-    nakagami_distribution
+    nakagami_distribution : private std::__random_not_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -1184,8 +1146,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private std::__random_not_eq::__tag
       {
 	typedef nakagami_distribution<result_type> distribution_type;
 
@@ -1374,15 +1337,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       std::gamma_distribution<result_type> _M_gd;
     };
 
-  /**
-   * @brief Return true if two Nakagami distributions are not equal.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const nakagami_distribution<_RealType>& __d1,
-	       const nakagami_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
 
   /**
    * @brief A Pareto continuous distribution for random numbers.
@@ -1409,7 +1363,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    */
   template<typename _RealType = double>
     class
-    pareto_distribution
+    pareto_distribution : private std::__random_not_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -1417,8 +1371,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private std::__random_not_eq::__tag
       {
 	typedef pareto_distribution<result_type> distribution_type;
 
@@ -1610,15 +1565,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       std::uniform_real_distribution<result_type> _M_ud;
     };
 
-  /**
-   * @brief Return true if two Pareto distributions are not equal.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const pareto_distribution<_RealType>& __d1,
-	       const pareto_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
 
   /**
    * @brief A K continuous distribution for random numbers.
@@ -1643,7 +1589,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    */
   template<typename _RealType = double>
     class
-    k_distribution
+    k_distribution : private std::__random_not_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -1651,8 +1597,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private std::__random_not_eq::__tag
       {
 	typedef k_distribution<result_type> distribution_type;
 
@@ -1854,15 +1801,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       std::gamma_distribution<result_type> _M_gd2;
     };
 
-  /**
-   * @brief Return true if two K distributions are not equal.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const k_distribution<_RealType>& __d1,
-	       const k_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
 
   /**
    * @brief An arcsine continuous distribution for random numbers.
@@ -1882,7 +1820,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    */
   template<typename _RealType = double>
     class
-    arcsine_distribution
+    arcsine_distribution : private std::__random_not_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -1890,8 +1828,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private std::__random_not_eq::__tag
       {
 	typedef arcsine_distribution<result_type> distribution_type;
 
@@ -2084,15 +2023,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       std::uniform_real_distribution<result_type> _M_ud;
     };
 
-  /**
-   * @brief Return true if two arcsine distributions are not equal.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const arcsine_distribution<_RealType>& __d1,
-	       const arcsine_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
 
   /**
    * @brief A Hoyt continuous distribution for random numbers.
@@ -2118,7 +2048,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    */
   template<typename _RealType = double>
     class
-    hoyt_distribution
+    hoyt_distribution : private std::__random_not_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -2126,8 +2056,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private std::__random_not_eq::__tag
       {
 	typedef hoyt_distribution<result_type> distribution_type;
 
@@ -2321,15 +2252,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       std::exponential_distribution<result_type> _M_ed;
     };
 
-  /**
-   * @brief Return true if two Hoyt distributions are not equal.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const hoyt_distribution<_RealType>& __d1,
-	       const hoyt_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
 
   /**
    * @brief A triangular distribution for random numbers.
@@ -2351,7 +2273,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * </table>
    */
   template<typename _RealType = double>
-    class triangular_distribution
+    class triangular_distribution : private std::__random_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -2359,8 +2281,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private std::__random_not_eq::__tag
       {
 	friend class triangular_distribution<_RealType>;
 
@@ -2525,16 +2448,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	{ this->__generate_impl(__f, __t, __urng, __p); }
 
       /**
-       * @brief Return true if two triangle distributions have the same
-       *        parameters and the sequences that would be generated
-       *        are equal.
-       */
-      friend bool
-      operator==(const triangular_distribution& __d1,
-		 const triangular_distribution& __d2)
-      { return __d1._M_param == __d2._M_param; }
-
-      /**
        * @brief Inserts a %triangular_distribution random number distribution
        * @p __x into the output stream @p __os.
        *
@@ -2574,15 +2487,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       param_type _M_param;
     };
 
-  /**
-   * @brief Return true if two triangle distributions are different.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const __gnu_cxx::triangular_distribution<_RealType>& __d1,
-	       const __gnu_cxx::triangular_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
 
   /**
    * @brief A von Mises distribution for random numbers.
@@ -2607,7 +2511,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * </table>
    */
   template<typename _RealType = double>
-    class von_mises_distribution
+    class von_mises_distribution : private std::__random_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -2615,8 +2519,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private std::__random_not_eq::__tag
       {
 	friend class von_mises_distribution<_RealType>;
 
@@ -2760,16 +2665,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	{ this->__generate_impl(__f, __t, __urng, __p); }
 
       /**
-       * @brief Return true if two von Mises distributions have the same
-       *        parameters and the sequences that would be generated
-       *        are equal.
-       */
-      friend bool
-      operator==(const von_mises_distribution& __d1,
-		 const von_mises_distribution& __d2)
-      { return __d1._M_param == __d2._M_param; }
-
-      /**
        * @brief Inserts a %von_mises_distribution random number distribution
        * @p __x into the output stream @p __os.
        *
@@ -2809,15 +2704,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       param_type _M_param;
     };
 
-  /**
-   * @brief Return true if two von Mises distributions are different.
-   */
-  template<typename _RealType>
-    inline bool
-    operator!=(const __gnu_cxx::von_mises_distribution<_RealType>& __d1,
-	       const __gnu_cxx::von_mises_distribution<_RealType>& __d2)
-    { return !(__d1 == __d2); }
-
 
   /**
    * @brief A discrete hypergeometric random number distribution.
@@ -2843,7 +2729,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * </table>
    */
   template<typename _UIntType = unsigned int>
-    class hypergeometric_distribution
+    class hypergeometric_distribution : private std::__random_eq::__tag
     {
       static_assert(std::is_unsigned<_UIntType>::value, "template argument "
 		    "substituting _UIntType not an unsigned integral type");
@@ -2853,7 +2739,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       typedef _UIntType  result_type;
 
       /** Parameter type. */
-      struct param_type
+      struct param_type : private std::__random_not_eq::__tag
       {
 	typedef hypergeometric_distribution<_UIntType> distribution_type;
 	friend class hypergeometric_distribution<_UIntType>;
@@ -3015,16 +2901,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		   const param_type& __p)
 	{ this->__generate_impl(__f, __t, __urng, __p); }
 
-       /**
-	* @brief Return true if two hypergeometric distributions have the same
-	*        parameters and the sequences that would be generated
-	*        are equal.
-	*/
-      friend bool
-      operator==(const hypergeometric_distribution& __d1,
-		 const hypergeometric_distribution& __d2)
-      { return __d1._M_param == __d2._M_param; }
-
       /**
        * @brief Inserts a %hypergeometric_distribution random number
        * distribution @p __x into the output stream @p __os.
@@ -3070,14 +2946,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       param_type _M_param;
     };
 
-  /**
-   * @brief Return true if two hypergeometric distributions are different.
-   */
-  template<typename _UIntType>
-    inline bool
-    operator!=(const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d1,
-	       const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d2)
-    { return !(__d1 == __d2); }
 
   /**
    * @brief A logistic continuous distribution for random numbers.
@@ -3103,7 +2971,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    */
   template<typename _RealType = double>
     class
-    logistic_distribution
+    logistic_distribution : private std::__random_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -3111,8 +2979,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef _RealType result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private std::__random_not_eq::__tag
       {
 	typedef logistic_distribution<result_type> distribution_type;
 
@@ -3240,17 +3109,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	{ this->__generate_impl(__f, __t, __urng, __p); }
 
       /**
-       * @brief Return true if two logistic distributions have
-       *        the same parameters and the sequences that would
-       *        be generated are equal.
-       */
-      template<typename _RealType1>
-	friend bool
-	operator==(const logistic_distribution<_RealType1>& __d1,
-		   const logistic_distribution<_RealType1>& __d2)
-	{ return __d1.param() == __d2.param(); }
-
-      /**
        * @brief Inserts a %logistic_distribution random number distribution
        * @p __x into the output stream @p __os.
        *
@@ -3291,15 +3149,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       param_type _M_param;
     };
 
-  /**
-   * @brief Return true if two logistic distributions are not equal.
-   */
-  template<typename _RealType1>
-    inline bool
-    operator!=(const logistic_distribution<_RealType1>& __d1,
-	       const logistic_distribution<_RealType1>& __d2)
-    { return !(__d1 == __d2); }
-
 
   /**
    * @brief A distribution for random coordinates on a unit sphere.
@@ -3308,7 +3157,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * to G. W. Brown, Modern Mathematics for the Engineer (1956).
    */
   template<std::size_t _Dimen, typename _RealType = double>
-    class uniform_on_sphere_distribution
+    class uniform_on_sphere_distribution : private std::__random_not_eq::__tag
     {
       static_assert(std::is_floating_point<_RealType>::value,
 		    "template argument not a floating point type");
@@ -3317,8 +3166,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     public:
       /** The type of the range of the distribution. */
       typedef std::array<_RealType, _Dimen> result_type;
+
       /** Parameter type. */
-      struct param_type
+      struct param_type : private std::__random_not_eq::__tag
       {
 	explicit
 	param_type()
@@ -3482,17 +3332,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       std::normal_distribution<_RealType> _M_nd;
     };
 
-  /**
-   * @brief Return true if two uniform on sphere distributions are different.
-   */
-  template<std::size_t _Dimen, typename _RealType>
-    inline bool
-    operator!=(const __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
-	       _RealType>& __d1,
-	       const __gnu_cxx::uniform_on_sphere_distribution<_Dimen,
-	       _RealType>& __d2)
-    { return !(__d1 == __d2); }
-
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace __gnu_cxx
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]