[PATCH v2] libstdc++: Change piecewise distribution densities to return vector<result_type> [PR82749]

Jonathan Wakely jwakely@redhat.com
Mon Jul 13 17:26:11 GMT 2026


On Mon, 01 Jun 2026 at 09:21 +0200, Tomasz Kamiński wrote:
>This implements the interface changes from
>LWG1439, "Return from densities() functions?".
>
>Due the ABI concerns, we cannot change the the element_type of member
>(_M_den, _M_cp, and _M_m) vectors, and we convert the _M_den values
>to result_type when function is invoked. However, as the usage of
>distributions with types other than float, double, and long double
>is either undefined (pre C++26) or implementaiton-defined (post C++26),
>this limitation de-fact applies to float, and long double (if it's
>different size than double).
>
>To handle above we introduce the __piecewise_distributions_storage<_Tp>
>struct, whose type nested typedef points to double in above two cases,
>and _Tp otherwise. The _StorageType is defined in terms of
>__piecewise_distributions_storage_t alias to above, and is then used
>in defintion of _M_den, _M_cp, and _M_m members. In consequence for
>extended floating point types (__float128, std::float16, ...) for which
>ABI can be changed, we store densitiees (and other values) as result_type.
>
>To avoid symbol conflicts, the param_type::densities member functions
>are marked with "__rt" ABI tag. The corresponding members of the
>distributions are modified to invoke param_type method, and marked
>as always_inline. For consistency intervals methods are adjusted same
>way.
>
>To preserve current behavior, the operators>> load densities
>as values of _StorageType.
>
>Finally, we introduce _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS, that
>revers above changes, restoring old behavior for all floating point
>types. Additionally for the users accept above ABI change,
>we introduce a macro _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES,
>that result in __piecewise_distributions_storage_t being unconditionally
>defined as _Tp, and thus adjust internal storage also for float and long
>double.
>
>	libstdc++ PR/82749
>
>libstdc++-v3/ChangeLog:
>
>	* doc/xml/manual/using.xml
>	(_GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS): Add entry.
>	(_GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES): Add entry.
>	* doc/html/manual/using_macros.html: Regenerate.
>	* include/bits/random.h
>	(__detail::__piecewise_distributions_storage)
>	(__detail::__piecewise_distributions_storage_t)
>	(piecewise_constant_distribution::_StorageType)
>	(piecewise_linear_distribution::_StorageType): Define.
>	(piecewise_constant_distribution::param_type::_M_den)
>	(piecewise_constant_distribution::param_type::_M_cp)
>	(piecewise_linear_distribution::param_type::_M_den)
>	(piecewise_linear_distribution::param_type::_M_cp)
>	(piecewise_linear_distribution::param_type::_M_m): Use _StorageType
>	as element type.
>	(piecewise_constant_distribution::param_type::densities)
>	(piecewise_linear_distribution::param_type::densities)
>	[!_GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS]: Change return type
>	to vector<result_type>, mark with "__rt" ABI tag, and adjust
>	implementation.
>	(piecewise_constant_distribution::param_type::intervals)
>	(piecewise_linear_distribution::param_type::intervals): Use
>	result_type alias in return type.
>	(piecewise_constant_distribution::densities)
>	(piecewise_linear_distribution::densities): Delegate to param_type
>	method, additional change return type and  mark as always_inline
>	if _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS is not defined.
>	(piecewise_constant_distribution::intervals)
>	(piecewise_linear_distribution::intervals): Delegate to param_type
>	method and use result_type alias in return type.
>	* include/bits/random.tcc
>	(operator<<(basic_ostream&, const piecewise_constant_distribution&))
>	(operator<<(basic_ostream&, const piecewise_linear_distribution&)):
>	Parse vector of _StorageType for densities, to preserve behavior.
>	* testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors.cc:
>	New test.
>	* testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors.cc:
>	New test.
>	* testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors_exact.cc:
>	Run accessors.cc with _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES.
>	* testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors_exact.cc:
>	Likewise.
>	* testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors_fallback.cc:
>	Run accessors.cc with _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS.
>	* testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors_fallback.cc:
>	Likewise.
>---
>v2 adds also _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS, that
>reverts the changes. I plan to use it for all changes made
>to this distributions in GCC-17.
>Additionally
>* updates and add PR link to commit description
>* add accessorrs_fallback.cc tests
>* use result_type in return consistently on new path
>
>Resated *piecewise* test. Testing on x86_64-linux.
>OK for trunk?
>
> .../doc/html/manual/using_macros.html         |  19 +++
> libstdc++-v3/doc/xml/manual/using.xml         |  29 ++++
> libstdc++-v3/include/bits/random.h            | 154 +++++++++++++-----
> libstdc++-v3/include/bits/random.tcc          |   8 +-
> .../operators/accessors.cc                    |  83 ++++++++++
> .../operators/accessors_exact.cc              |   5 +
> .../operators/accessors_fallback.cc           |   5 +
> .../operators/accessors.cc                    |  85 ++++++++++
> .../operators/accessors_exact.cc              |   5 +
> .../operators/accessors_fallback.cc           |   5 +
> 10 files changed, 359 insertions(+), 39 deletions(-)
> create mode 100644 libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors.cc
> create mode 100644 libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors_exact.cc
> create mode 100644 libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors_fallback.cc
> create mode 100644 libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors.cc
> create mode 100644 libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors_exact.cc
> create mode 100644 libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors_fallback.cc
>
>diff --git a/libstdc++-v3/doc/html/manual/using_macros.html b/libstdc++-v3/doc/html/manual/using_macros.html
>index f1d8492fb9e..4be2ab576dc 100644
>--- a/libstdc++-v3/doc/html/manual/using_macros.html
>+++ b/libstdc++-v3/doc/html/manual/using_macros.html
>@@ -156,4 +156,23 @@
> 	<code class="option">-fexec-charset=UTF-8</code> so might give incorrect results
> 	if called from a source file that uses a non-Unicode encoding,
> 	especially for format strings using non-ASCII fill characters.
>+      </p></dd><dt><span class="term"><code class="code">_GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS</code></span></dt><dd><p>
>+	Undefined by default.
>+	When defined, the behaviour specializations of
>+	<code class="code">piecewise_constant_distribution</code> and
>+	<code class="code">piecewise_linear_distribution</code> for
>+	their behavior to the state prior the implementation
>+	of <a class="link" href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82749" target="_top">
>+	PR82749</a> (<a class="link" href="https://cplusplus.github.io/LWG/lwg-defects.html#1439" target="_top">
>+	LWG1439</a>) in GCC-17.

Oh and also, "GCC 17" with a space, not GCC-17

>+      </p></dd><dt><span class="term"><code class="code">_GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES</code></span></dt><dd><p>
>+	Undefined by default. ABI-changing.
>+	When defined, specializations of
>+	<code class="code">piecewise_constant_distribution</code> and
>+	<code class="code">piecewise_linear_distribution</code> with a
>+	<code class="code">result_type</code> of either <code class="code">float</code> or
>+	<code class="code">long double</code> will manage their internal state using
>+	<code class="code">result_type</code> values (instead of <code class="code">double</code>).
>+	This is required for standard conformance, but is incompatible with
>+	the default implementation of those class templates
>       </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="using_headers.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="using.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="using_dual_abi.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Headers </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Dual ABI</td></tr></table></div></body></html>
>\ No newline at end of file
>diff --git a/libstdc++-v3/doc/xml/manual/using.xml b/libstdc++-v3/doc/xml/manual/using.xml
>index e2e75e8fe28..1759eb5a214 100644
>--- a/libstdc++-v3/doc/xml/manual/using.xml
>+++ b/libstdc++-v3/doc/xml/manual/using.xml
>@@ -1379,6 +1379,35 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 hello.cc -o test.exe
> 	especially for format strings using non-ASCII fill characters.
>       </para>
>     </listitem></varlistentry>
>+    <varlistentry><term><code>_GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS</code></term>
>+     <listitem>
>+      <para>
>+	Undefined by default.
>+	When defined, the behaviour specializations of
>+	<code>piecewise_constant_distribution</code> and
>+	<code>piecewise_linear_distribution</code> for
>+	their behavior to the state prior the implementation
>+	of <link xmlns:xlink="http://www.w3.org/1999/xlink"
>+	xlink:href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82749">
>+	PR82749</link> (<link xmlns:xlink="http://www.w3.org/1999/xlink"
>+	xlink:href="https://cplusplus.github.io/LWG/lwg-defects.html#1439">
>+	LWG1439</link>) in GCC-17.
>+      </para>
>+    </listitem></varlistentry>
>+    <varlistentry><term><code>_GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES</code></term>
>+    <listitem>
>+      <para>
>+	Undefined by default. ABI-changing.
>+	When defined, specializations of
>+	<code>piecewise_constant_distribution</code> and
>+	<code>piecewise_linear_distribution</code> with a
>+	<code>result_type</code> of either <code>float</code> or
>+	<code>long double</code> will manage their internal state using
>+	<code>result_type</code> values (instead of <code>double</code>).
>+	This is required for standard conformance, but is incompatible with
>+	the default implementation of those class templates
>+      </para>
>+    </listitem></varlistentry>
>     </variablelist>
>
>   </section>
>diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h
>index a0592a00763..6b82d1120b7 100644
>--- a/libstdc++-v3/include/bits/random.h
>+++ b/libstdc++-v3/include/bits/random.h
>@@ -6385,6 +6385,40 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
>     { return !(__d1 == __d2); }
> #endif
>
>+  namespace __detail
>+  {
>+#ifdef _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES
>+    template<typename _Tp>
>+      using __piecewise_distributions_storage_t = _Tp;
>+#else
>+    template<typename _Tp>
>+      struct __piecewise_distributions_storage
>+      { using type = _Tp; };
>+
>+    template<>
>+      struct __piecewise_distributions_storage<float>
>+      { using type = double; };
>+
>+# ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
>+    template<>
>+      struct __piecewise_distributions_storage<__ibm128>
>+      { using type = double; };
>+
>+    template<>
>+      struct __piecewise_distributions_storage<__ieee128>
>+      { using type = double; };
>+# elif __LDBL_MANT_DIG__ != __DBL_MANT_DIG__
>+    template<>
>+      struct __piecewise_distributions_storage<long double>
>+      { using type = double; };
>+# endif
>+
>+    template<typename _Tp>
>+       using __piecewise_distributions_storage_t
>+	= typename __piecewise_distributions_storage<_Tp>::type;
>+#endif // _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES
>+  }
>+
>   /**
>    * @brief A piecewise_constant_distribution random number distribution.
>    *
>@@ -6407,6 +6441,9 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
>       static_assert(std::is_floating_point<_RealType>::value,
> 		    "result_type must be a floating point type");
>
>+      using _StorageType
>+	= __detail::__piecewise_distributions_storage_t<_RealType>;
>+
>     public:
>       /** The type of the range of the distribution. */
>       typedef _RealType result_type;
>@@ -6437,7 +6474,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
> 	param_type(const param_type&) = default;
> 	param_type& operator=(const param_type&) = default;
>
>-	std::vector<_RealType>
>+	std::vector<result_type>
> 	intervals() const
> 	{
> 	  if (_M_int.empty())
>@@ -6450,9 +6487,34 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
> 	    return _M_int;
> 	}
>
>+#ifdef _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS
> 	std::vector<double>
> 	densities() const
> 	{ return _M_den.empty() ? std::vector<double>(1, 1.0) : _M_den; }
>+#else
>+	// _GLIBCXX_RESOLVE_LIB_DEFECTS
>+	// 1439. Return from densities() functions?
>+	[[__gnu__::__abi_tag__("__rt")]]
>+	std::vector<result_type>
>+	densities() const
>+	{
>+#pragma GCC diagnostic push
>+#pragma GCC diagnostic ignored "-Wc++17-extensions"
>+	  if (_M_den.empty())
>+	    return std::vector<_RealType>(1, _RealType(1));
>+	  else if constexpr (is_same<_RealType, _StorageType>::value)
>+	    return _M_den;
>+	  else
>+	    {
>+	      std::vector<_RealType> __res;
>+	      __res.reserve(_M_den.size());
>+	      for (_RealType __v : _M_den)
>+		__res.push_back(__v);
>+	      return __res;
>+	    }
>+#pragma GCC diagnostic pop
>+	}
>+#endif
>
> 	friend bool
> 	operator==(const param_type& __p1, const param_type& __p2)
>@@ -6472,8 +6534,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
> 	_M_initialize2(const _RealType* __ints, _RealType __den);
>
> 	std::vector<_RealType> _M_int;
>-	std::vector<double> _M_den;
>-	std::vector<double> _M_cp;
>+	std::vector<_StorageType> _M_den;
>+	std::vector<_StorageType> _M_cp;
>
> 	template<typename _RealType1, typename _CharT, typename _Traits>
> 	  friend std::basic_ostream<_CharT, _Traits>&
>@@ -6520,28 +6582,23 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
>       /**
>        * @brief Returns a vector of the intervals.
>        */
>-      std::vector<_RealType>
>+      std::vector<result_type>
>       intervals() const
>-      {
>-	if (_M_param._M_int.empty())
>-	  {
>-	    std::vector<_RealType> __tmp(2);
>-	    __tmp[1] = _RealType(1);
>-	    return __tmp;
>-	  }
>-	else
>-	  return _M_param._M_int;
>-      }
>+      { return _M_param.intervals(); }
>
>       /**
>        * @brief Returns a vector of the probability densities.
>        */
>+#ifdef _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS
>       std::vector<double>
>       densities() const
>-      {
>-	return _M_param._M_den.empty()
>-	  ? std::vector<double>(1, 1.0) : _M_param._M_den;
>-      }
>+      { return _M_param.densities(); }
>+#else
>+      [[__gnu__::__always_inline__]]
>+      std::vector<result_type>
>+      densities() const
>+      { return _M_param.densities(); }
>+#endif
>
>       /**
>        * @brief Returns the parameter set of the distribution.
>@@ -6695,6 +6752,9 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
>       static_assert(std::is_floating_point<_RealType>::value,
> 		    "result_type must be a floating point type");
>
>+      using _StorageType
>+	= __detail::__piecewise_distributions_storage_t<_RealType>;
>+
>     public:
>       /** The type of the range of the distribution. */
>       typedef _RealType result_type;
>@@ -6725,7 +6785,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
> 	param_type(const param_type&) = default;
> 	param_type& operator=(const param_type&) = default;
>
>-	std::vector<_RealType>
>+	std::vector<result_type>
> 	intervals() const
> 	{
> 	  if (_M_int.empty())
>@@ -6738,9 +6798,34 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
> 	    return _M_int;
> 	}
>
>+#ifdef _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS
> 	std::vector<double>
> 	densities() const
> 	{ return _M_den.empty() ? std::vector<double>(2, 1.0) : _M_den; }
>+#else
>+	// _GLIBCXX_RESOLVE_LIB_DEFECTS
>+	// 1439. Return from densities() functions?
>+	[[__gnu__::__abi_tag__("__rt")]]
>+	std::vector<result_type>
>+	densities() const
>+	{
>+#pragma GCC diagnostic push
>+#pragma GCC diagnostic ignored "-Wc++17-extensions"
>+	  if (_M_den.empty())
>+	    return std::vector<_RealType>(2, _RealType(1));
>+	  else if constexpr (is_same<_RealType, _StorageType>::value)
>+	    return _M_den;
>+	  else
>+	    {
>+	      std::vector<_RealType> __res;
>+	      __res.reserve(_M_den.size());
>+	      for (_RealType __v : _M_den)
>+		__res.push_back(__v);
>+	      return __res;
>+	    }
>+#pragma GCC diagnostic pop
>+	}
>+#endif
>
> 	friend bool
> 	operator==(const param_type& __p1, const param_type& __p2)
>@@ -6760,9 +6845,9 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
> 	_M_initialize2(const _RealType* __ints, const _RealType* __dens);
>
> 	std::vector<_RealType> _M_int;
>-	std::vector<double> _M_den;
>-	std::vector<double> _M_cp;
>-	std::vector<double> _M_m;
>+	std::vector<_StorageType> _M_den;
>+	std::vector<_StorageType> _M_cp;
>+	std::vector<_StorageType> _M_m;
>
> 	template<typename _RealType1, typename _CharT, typename _Traits>
> 	  friend std::basic_ostream<_CharT, _Traits>&
>@@ -6809,29 +6894,24 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
>       /**
>        * @brief Return the intervals of the distribution.
>        */
>-      std::vector<_RealType>
>+      std::vector<result_type>
>       intervals() const
>-      {
>-	if (_M_param._M_int.empty())
>-	  {
>-	    std::vector<_RealType> __tmp(2);
>-	    __tmp[1] = _RealType(1);
>-	    return __tmp;
>-	  }
>-	else
>-	  return _M_param._M_int;
>-      }
>+      { return _M_param.intervals(); }
>
>       /**
>        * @brief Return a vector of the probability densities of the
>        *        distribution.
>        */
>+#ifdef _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS
>       std::vector<double>
>       densities() const
>-      {
>-	return _M_param._M_den.empty()
>-	  ? std::vector<double>(2, 1.0) : _M_param._M_den;
>-      }
>+      { return _M_param.densities(); }
>+#else
>+      [[__gnu__::__always_inline__]]
>+      std::vector<result_type>
>+      densities() const
>+      { return _M_param.densities(); }
>+#endif
>
>       /**
>        * @brief Returns the parameter set of the distribution.
>diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc
>index e581f912764..6c88d68d3e4 100644
>--- a/libstdc++-v3/include/bits/random.tcc
>+++ b/libstdc++-v3/include/bits/random.tcc
>@@ -3199,6 +3199,8 @@ namespace __detail
> 	       piecewise_constant_distribution<_RealType>& __x)
>     {
>       using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
>+      using _StorageType
>+	= typename piecewise_constant_distribution<_RealType>::_StorageType;
>
>       const typename __ios_base::fmtflags __flags = __is.flags();
>       __is.flags(__ios_base::dec | __ios_base::skipws);
>@@ -3209,7 +3211,7 @@ namespace __detail
> 	  std::vector<_RealType> __int_vec;
> 	  if (__detail::__extract_params(__is, __int_vec, __n + 1))
> 	    {
>-	      std::vector<double> __den_vec;
>+	      std::vector<_StorageType> __den_vec;
> 	      if (__detail::__extract_params(__is, __den_vec, __n))
> 		{
> 		  __x.param({ __int_vec.begin(), __int_vec.end(),
>@@ -3466,6 +3468,8 @@ namespace __detail
> 	       piecewise_linear_distribution<_RealType>& __x)
>     {
>       using __ios_base = typename basic_istream<_CharT, _Traits>::ios_base;
>+      using _StorageType
>+	= typename piecewise_linear_distribution<_RealType>::_StorageType;
>
>       const typename __ios_base::fmtflags __flags = __is.flags();
>       __is.flags(__ios_base::dec | __ios_base::skipws);
>@@ -3476,7 +3480,7 @@ namespace __detail
> 	  vector<_RealType> __int_vec;
> 	  if (__detail::__extract_params(__is, __int_vec, __n + 1))
> 	    {
>-	      vector<double> __den_vec;
>+	      vector<_StorageType> __den_vec;
> 	      if (__detail::__extract_params(__is, __den_vec, __n + 1))
> 		{
> 		  __x.param({ __int_vec.begin(), __int_vec.end(),
>diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors.cc
>new file mode 100644
>index 00000000000..219d1949040
>--- /dev/null
>+++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors.cc
>@@ -0,0 +1,83 @@
>+// { dg-do run { target c++11 } }
>+// { dg-require-cstdint "" }
>+
>+#include <random>
>+#include <testsuite_hooks.h>
>+
>+template<typename RealType>
>+void
>+test_exact()
>+{
>+  RealType x[6] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
>+  RealType wt[5] = {0.5, 1.0, 3.5, 2.5, 0.5};
>+
>+  std::piecewise_constant_distribution<RealType>
>+    u(std::begin(x), std::end(x), wt);
>+
>+  const std::vector<RealType>& interval = u.intervals();
>+  VERIFY( interval.size() == 6 );
>+  VERIFY( interval[0] == RealType(0.0) );
>+  VERIFY( interval[5] == RealType(5.0) );
>+
>+#ifdef _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS
>+  const std::vector<double>& density = u.densities();
>+#else
>+  const std::vector<RealType>& density = u.densities();
>+#endif
>+
>+  VERIFY( density.size() == 5 );
>+  VERIFY( density[0] == RealType(0.5 / 8.0) );
>+  VERIFY( density[1] == RealType(1.0 / 8.0) );
>+  VERIFY( density[2] == RealType(3.5 / 8.0) );
>+  VERIFY( density[3] == RealType(2.5 / 8.0) );
>+  VERIFY( density[4] == RealType(0.5 / 8.0) );
>+}
>+
>+template<typename RealType>
>+void
>+test_precision_depended()
>+{
>+  constexpr bool preserved
>+#ifdef _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES
>+    = true;
>+#else
>+    = sizeof(RealType) <= sizeof(double);
>+#endif
>+
>+  RealType x[3]{0.0, 0.5, 1.0};
>+  constexpr RealType step
>+    = std::numeric_limits<RealType>::epsilon();
>+  RealType wt[2]{RealType(1) - step, RealType(1) + step};
>+
>+  std::piecewise_constant_distribution<RealType>
>+    u(std::begin(x), std::end(x), wt);
>+
>+  const std::vector<RealType>& interval = u.intervals();
>+  VERIFY( interval.size() == 3 );
>+  VERIFY( interval[0] == RealType(0.0) );
>+  VERIFY( interval[2] == RealType(1.0) );
>+
>+#ifdef _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS
>+  const std::vector<double>& density = u.densities();
>+#else
>+  const std::vector<RealType>& density = u.densities();
>+#endif
>+
>+  VERIFY( density.size() == 2 );
>+  VERIFY( density[0] == (preserved ? wt[0] : RealType(1)) );
>+  VERIFY( density[1] == (preserved ? wt[1] : RealType(1)) );
>+}
>+
>+int main()
>+{
>+  using namespace __gnu_test;
>+  test_exact<float>();
>+  test_exact<double>();
>+  test_exact<long double>();
>+
>+  test_precision_depended<float>();
>+  test_precision_depended<double>();
>+  test_precision_depended<long double>();
>+
>+  return 0;
>+}
>diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors_exact.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors_exact.cc
>new file mode 100644
>index 00000000000..469ed3fac46
>--- /dev/null
>+++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors_exact.cc
>@@ -0,0 +1,5 @@
>+// { dg-options "-D_GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES" }
>+// { dg-do run { target c++11 } }
>+// { dg-require-cstdint "" }
>+#include "accessors.cc"
>+
>diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors_fallback.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors_fallback.cc
>new file mode 100644
>index 00000000000..3e2fbf03430
>--- /dev/null
>+++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors_fallback.cc
>@@ -0,0 +1,5 @@
>+// { dg-options "-D_GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS" }
>+// { dg-do run { target c++11 } }
>+// { dg-require-cstdint "" }
>+#include "accessors.cc"
>+
>diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors.cc
>new file mode 100644
>index 00000000000..d3855ee0291
>--- /dev/null
>+++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors.cc
>@@ -0,0 +1,85 @@
>+// { dg-do run { target c++11 } }
>+// { dg-require-cstdint "" }
>+
>+#include <random>
>+#include <testsuite_hooks.h>
>+
>+template<typename RealType>
>+void
>+test_exact()
>+{
>+  RealType x[6] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
>+  RealType wt[6] = {0.0, 1.0, 1.0, 6.0, -1.0, 2.0};
>+
>+  std::piecewise_linear_distribution<RealType>
>+    u(std::begin(x), std::end(x), wt);
>+
>+  const std::vector<RealType>& interval = u.intervals();
>+  VERIFY( interval.size() == 6 );
>+  VERIFY( interval[0] == RealType(0.0) );
>+  VERIFY( interval[5] == RealType(5.0) );
>+
>+#ifdef _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS
>+  const std::vector<double>& density = u.densities();
>+#else
>+  const std::vector<RealType>& density = u.densities();
>+#endif
>+
>+  VERIFY( density.size() == 6 );
>+  VERIFY( density[0] == RealType(0.0 / 8.0) );
>+  VERIFY( density[1] == RealType(1.0 / 8.0) );
>+  VERIFY( density[2] == RealType(1.0 / 8.0) );
>+  VERIFY( density[3] == RealType(6.0 / 8.0) );
>+  VERIFY( density[4] == RealType(-1.0 / 8.0) );
>+  VERIFY( density[5] == RealType(2.0 / 8.0) );
>+}
>+
>+template<typename RealType>
>+void
>+test_precision_depended()
>+{
>+  constexpr bool preserved
>+#ifdef _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES
>+    = true;
>+#else
>+    = sizeof(RealType) <= sizeof(double);
>+#endif
>+
>+  RealType x[3]{0.0, 0.5, 1.0};
>+  constexpr RealType step
>+    = std::numeric_limits<RealType>::epsilon() * 2;
>+  RealType wt[3]{RealType(1) - step, RealType(1), RealType(1) + step};
>+
>+  std::piecewise_linear_distribution<RealType>
>+    u(std::begin(x), std::end(x), wt);
>+
>+  const std::vector<RealType>& interval = u.intervals();
>+  VERIFY( interval.size() == 3 );
>+  VERIFY( interval[0] == RealType(0.0) );
>+  VERIFY( interval[2] == RealType(1.0) );
>+
>+#ifdef _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS
>+  const std::vector<double>& density = u.densities();
>+#else
>+  const std::vector<RealType>& density = u.densities();
>+#endif
>+
>+  VERIFY( density.size() == 3 );
>+  VERIFY( density[0] == (preserved ? wt[0] : RealType(1)) );
>+  VERIFY( density[1] == RealType(1) );
>+  VERIFY( density[2] == (preserved ? wt[2] : RealType(1)) );
>+}
>+
>+int main()
>+{
>+  using namespace __gnu_test;
>+  test_exact<float>();
>+  test_exact<double>();
>+  test_exact<long double>();
>+
>+  test_precision_depended<float>();
>+  test_precision_depended<double>();
>+  test_precision_depended<long double>();
>+
>+  return 0;
>+}
>diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors_exact.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors_exact.cc
>new file mode 100644
>index 00000000000..469ed3fac46
>--- /dev/null
>+++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors_exact.cc
>@@ -0,0 +1,5 @@
>+// { dg-options "-D_GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES" }
>+// { dg-do run { target c++11 } }
>+// { dg-require-cstdint "" }
>+#include "accessors.cc"
>+
>diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors_fallback.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors_fallback.cc
>new file mode 100644
>index 00000000000..3e2fbf03430
>--- /dev/null
>+++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors_fallback.cc
>@@ -0,0 +1,5 @@
>+// { dg-options "-D_GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS" }
>+// { dg-do run { target c++11 } }
>+// { dg-require-cstdint "" }
>+#include "accessors.cc"
>+
>-- 
>2.54.0
>
>



More information about the Libstdc++ mailing list