[PATCH] libstdc++: Generate result_type bits of precision in piecewise distributions.
Jonathan Wakely
jwakely@redhat.com
Thu Jul 16 12:00:31 GMT 2026
On Thu, 16 Jul 2026 at 12:50, Tomasz Kamiński <tkaminsk@redhat.com> wrote:
>
> The piecewise distributions previously always generated a double value
> out of provided generator, regardless of the result_type (template
> parameter). This patch address above, by generating value of _RealType
> by default.
>
> Furthermore, this patch addresses LWG4052, "Bogus requirements for
> piecewise_linear_distribution" issue, by converting the inputs
> (from iterators, or provided weights functor) to RealType, instead
> of double. See input_type test included in this patch.
>
> For consistency the internal computations are now performed in RealType,
> instead of double. This reduces the precision if float it used, however
> due the ABI compatibility, double is still used for storage, unless
> _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES is defined (see
> test_precision_depended in accessors.cc) test.
>
> The above change leads to user-observable changes in the behaviour or
> distributions, both in produced outputs and number of calls to provided
> generator performed per each element (see test_engine_calls in accessors.cc).
> The pre-GCC17 behavior of distributions can be restored by defining
> _GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS (this also reverts r17-2391-geae19
> and r17-2392-g86a93). This is achieved by converting the values to _CalcType
> that is either defined as double or _RealType. This change is not applied
> to interval delta (_M_int[__k + 1] - _M_int[__k]) that used _RealType
> already, to preserve the result of computations involving it.
>
> To reduce the code duplication the __generate_one functions are introduced
> for both distributions. They are used both by the operator() and
> __generate_impl. The linear __generate_impl is now consistent with constant
> version, and simply assigns the result of generator invocation for default
> configuration.
>
> Finally, this made result of stream operator for float/double param_type
> of piecewise_linear_distribution consistent for 32bits/64bits. The
> float specialization for constant distribution still produces different
> result, however the calculated values are consistent when printed as
> hexfloat.
>
> libstdc++-v3/ChangeLog:
>
> * doc/html/manual/using_macros.html: Regenrate.
> * doc/xml/manual/using.xml
> (_GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS): Mention LWG4052.
> * include/bits/random.h
> (piecewise_constant_distribution::_CalcType)
> (piecewise_linear_distribution::_CalcType): Define.
> (piecewise_constant_distribution::__generate_one)
> (piecewise_linear_distribution::__generate_one): Declare.
> (piecewise_constant_distribution::_M_initialize2)
> (piecewise_linear_distribution::__M_initialize2): Adjust
> densities parameter to _CalcType.
> * include/bits/random.tcc (std::__normalize): Perform
> computation in the type of factor parameter.
> (piecewise_constant_distribution::_M_configure)
> (piecewise_linear_distribution::_M_configure): Use _CalcType.
> (piecewise_constant_distribution::param_type::param_type)
> (piecewise_constant_distribution::param_type::param_type):
> Cast the inputs to the _CalcType. Use _RealTyp e as input
There's a stray space in "_RealTyp e" here.
OK for trunk
> weight functor.
> (piecewise_constant_distribution::__generate_one)
> (piecewise_linear_distribution::__generate_one): Extract
> from operator() and use _CalcType.
> (piecewise_constant_distribution::operator())
> (piecewise_constant_distribution::__generate_impl).
> (piecewise_linear_distribution::operator()): Use __generate_one.
> (piecewise_linear_distribution::__generate_impl): Optimize
> _M_cp.empty() case and user __generate_one otherwise.
> * testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors.cc:
> (test_precision_depended): Expand test to cover all constructors,
> and inputs different from distribution result type.
> (test_engine_calls): New tests.
> * testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors.cc:
> Likewise.
> * testsuite/26_numerics/random/piecewise_constant_distribution/operators/serialize2.cc:
> Update values to accommodate the change in precision for float.
> Remove trailing whitespaces.
> * testsuite/26_numerics/random/piecewise_linear_distribution/operators/serialize2.cc:
> Likewise, and enable float/double test for i686.
> * testsuite/26_numerics/random/piecewise_constant_distribution/cons/input_type.cc:
> New test.
> * testsuite/26_numerics/random/piecewise_constant_distribution/cons/input_type_fallback_neg.cc:
> New test.
> * testsuite/26_numerics/random/piecewise_linear_distribution/cons/input_type.cc:
> New test.
> * testsuite/26_numerics/random/piecewise_linear_distribution/cons/input_type_fallback_neg.cc:
> New test.
>
> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
> ---
> v2:
> - renames _CompType to _CalcType,
> - cast the literals to _CalcType, keepign the calculations in it
> - apply fixup to commit description suggested on review,
> and add a sentece regarding interval delta not being
> changed to _CalcType: we also do not cast (_M_int[__k + 1] - _M_int[__k])
> in constant distribution for same reason,
> - some trailing whitespace fixes
>
> Testing on x86_64-linux. *piecewise* test passed in all standard
> modes, debug and -m32. OK for trunk?
>
> .../doc/html/manual/using_macros.html | 3 +-
> libstdc++-v3/doc/xml/manual/using.xml | 4 +-
> libstdc++-v3/include/bits/random.h | 24 ++-
> libstdc++-v3/include/bits/random.tcc | 203 +++++++++++-------
> .../cons/input_type.cc | 52 +++++
> .../cons/input_type_fallback_neg.cc | 55 +++++
> .../operators/accessors.cc | 90 ++++++--
> .../operators/serialize2.cc | 10 +-
> .../cons/input_type.cc | 52 +++++
> .../cons/input_type_fallback_neg.cc | 55 +++++
> .../operators/accessors.cc | 95 ++++++--
> .../operators/serialize2.cc | 15 +-
> 12 files changed, 521 insertions(+), 137 deletions(-)
> create mode 100644 libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/input_type.cc
> create mode 100644 libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/input_type_fallback_neg.cc
> create mode 100644 libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/input_type.cc
> create mode 100644 libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/input_type_fallback_neg.cc
>
> diff --git a/libstdc++-v3/doc/html/manual/using_macros.html b/libstdc++-v3/doc/html/manual/using_macros.html
> index 2e5f4b2e1a1..0df3a2d3451 100644
> --- a/libstdc++-v3/doc/html/manual/using_macros.html
> +++ b/libstdc++-v3/doc/html/manual/using_macros.html
> @@ -164,7 +164,8 @@
> is restored to their 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>), and <a class="link" href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125548" target="_top">
> + LWG1439</a>), <a class="link" href="https://cplusplus.github.io/LWG/lwg-defects.html#4052" target="_top">
> + LWG4052</a>, and <a class="link" href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125548" target="_top">
> PR125548</a>) in 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.
> diff --git a/libstdc++-v3/doc/xml/manual/using.xml b/libstdc++-v3/doc/xml/manual/using.xml
> index 027b26b72cf..da710be408f 100644
> --- a/libstdc++-v3/doc/xml/manual/using.xml
> +++ b/libstdc++-v3/doc/xml/manual/using.xml
> @@ -1391,7 +1391,9 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 hello.cc -o test.exe
> 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>), and <link xmlns:xlink="http://www.w3.org/1999/xlink"
> + LWG1439</link>), <link xmlns:xlink="http://www.w3.org/1999/xlink"
> + xlink:href="https://cplusplus.github.io/LWG/lwg-defects.html#4052">
> + LWG4052</link>, and <link xmlns:xlink="http://www.w3.org/1999/xlink"
> xlink:href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125548">
> PR125548</link>) in GCC 17.
> </para>
> diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h
> index c219930cc29..b01b92862cc 100644
> --- a/libstdc++-v3/include/bits/random.h
> +++ b/libstdc++-v3/include/bits/random.h
> @@ -6470,6 +6470,11 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
>
> using _StorageType
> = __detail::__piecewise_distributions_storage_t<_RealType>;
> +#ifdef _GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS
> + using _CalcType = double;
> +#else
> + using _CalcType = _RealType;
> +#endif
>
> public:
> /** The type of the range of the distribution. */
> @@ -6552,7 +6557,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
> _M_configure();
>
> void
> - _M_initialize2(const _RealType* __ints, _RealType __den);
> + _M_initialize2(const _RealType* __ints, _CalcType __den);
>
> std::vector<_RealType> _M_int;
> std::vector<_StorageType> _M_den;
> @@ -6733,6 +6738,11 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
> std::piecewise_constant_distribution<_RealType1>& __x);
>
> private:
> + template<typename _AdaptedUniformRandomNumberGenerator>
> + result_type
> + __generate_one(_AdaptedUniformRandomNumberGenerator& __aurng,
> + const param_type& __param);
> +
> template<typename _ForwardIterator,
> typename _UniformRandomNumberGenerator>
> void
> @@ -6775,6 +6785,11 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
>
> using _StorageType
> = __detail::__piecewise_distributions_storage_t<_RealType>;
> +#ifdef _GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS
> + using _CalcType = double;
> +#else
> + using _CalcType = _RealType;
> +#endif
>
> public:
> /** The type of the range of the distribution. */
> @@ -6857,7 +6872,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
> _M_configure();
>
> void
> - _M_initialize2(const _RealType* __ints, const _RealType* __dens);
> + _M_initialize2(const _RealType* __ints, const _CalcType* __dens);
>
> std::vector<_RealType> _M_int;
> std::vector<_StorageType> _M_den;
> @@ -7040,6 +7055,11 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
> std::piecewise_linear_distribution<_RealType1>& __x);
>
> private:
> + template<typename _AdaptedUniformRandomNumberGenerator>
> + result_type
> + __generate_one(_AdaptedUniformRandomNumberGenerator& __aurng,
> + const param_type& __param);
> +
> template<typename _ForwardIterator,
> typename _UniformRandomNumberGenerator>
> void
> diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc
> index bf402876eb2..aa176db4778 100644
> --- a/libstdc++-v3/include/bits/random.tcc
> +++ b/libstdc++-v3/include/bits/random.tcc
> @@ -78,13 +78,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> }
>
> template<typename _InputIterator, typename _OutputIterator,
> - typename _Tp>
> + typename _RealType>
> _OutputIterator
> __normalize(_InputIterator __first, _InputIterator __last,
> - _OutputIterator __result, const _Tp& __factor)
> + _OutputIterator __result, const _RealType& __factor)
> {
> for (; __first != __last; ++__first, (void) ++__result)
> - *__result = *__first / __factor;
> + *__result = _RealType(_RealType(*__first) / __factor);
> return __result;
> }
>
> @@ -2947,28 +2947,30 @@ namespace __detail
> piecewise_constant_distribution<_RealType>::param_type::
> _M_configure()
> {
> - const double __sum = std::accumulate(_M_den.begin(),
> - _M_den.end(), 0.0);
> + const _CalcType __sum = std::accumulate(_M_den.begin(), _M_den.end(),
> + _CalcType(0));
> __glibcxx_assert(__sum > 0);
>
> __detail::__normalize(_M_den.begin(), _M_den.end(), _M_den.begin(),
> __sum);
>
> + _CalcType __psum(0);
> _M_cp.reserve(_M_den.size());
> - std::partial_sum(_M_den.begin(), _M_den.end(),
> - std::back_inserter(_M_cp));
> + for (_CalcType __den : _M_den)
> + _M_cp.push_back(__psum += __den);
>
> // Make sure the last cumulative probability is one.
> - _M_cp[_M_cp.size() - 1] = 1.0;
> + _M_cp[_M_cp.size() - 1] = _CalcType(1);
>
> for (size_t __k = 0; __k < _M_den.size(); ++__k)
> - _M_den[__k] /= _M_int[__k + 1] - _M_int[__k];
> + _M_den[__k] = _CalcType(_CalcType(_M_den[__k])
> + / (_M_int[__k + 1] - _M_int[__k]));
> }
>
> template<typename _RealType>
> void
> piecewise_constant_distribution<_RealType>::param_type::
> - _M_initialize2(const _RealType* __ints, _RealType __den)
> + _M_initialize2(const _RealType* __ints, _CalcType __den)
> {
> if (__ints[0] == _RealType(0) && __ints[1] == _RealType(1))
> return;
> @@ -3041,9 +3043,11 @@ namespace __detail
> for (; __bbegin != __bend; ++__bbegin)
> _M_int.push_back(*__bbegin);
>
> + // _GLIBCXX_RESOLVE_LIB_DEFECTS
> + // 4052. Bogus requirements for piecewise_linear_distribution
> _M_den.reserve(_M_int.size() - 1);
> for (size_t __k = 0; __k < _M_int.size() - 1; (void)++__k, ++__wbegin)
> - _M_den.push_back(*__wbegin);
> + _M_den.push_back(_CalcType(*__wbegin));
>
> _M_configure();
> }
> @@ -3057,10 +3061,21 @@ namespace __detail
> if (__bl.size() < 2)
> return;
>
> + // _GLIBCXX_RESOLVE_LIB_DEFECTS
> + // 4052. Bogus requirements for piecewise_linear_distribution
> + auto __cfw = [&__fw](_RealType __n, _RealType __p)
> + {
> +#ifdef _GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS
> + return __fw(0.5 * (__n + __p));
> +#else
> + return _RealType(__fw(_RealType(0.5) * (__n + __p)));
> +#endif
> + };
> +
> if (__bl.size() == 2)
> {
> const _RealType *__ints = __bl.begin();
> - _RealType __den = __fw(0.5 * (__ints[1] + __ints[0]));
> + _CalcType __den = __cfw(__ints[1], __ints[0]);
> _M_initialize2(__ints, __den);
> return;
> }
> @@ -3068,7 +3083,7 @@ namespace __detail
> _M_int = __bl;
> _M_den.reserve(_M_int.size() - 1);
> for (size_t __k = 0; __k < _M_int.size() - 1; ++__k)
> - _M_den.push_back(__fw(0.5 * (_M_int[__k + 1] + _M_int[__k])));
> + _M_den.push_back(__cfw(_M_int[__k + 1], _M_int[__k]));
>
> _M_configure();
> }
> @@ -3081,10 +3096,19 @@ namespace __detail
> {
> const size_t __n = __nw == 0 ? 1 : __nw;
> const _RealType __delta = (__xmax - __xmin) / __n;
> + auto __cfw = [&__fw, __delta](_RealType __v)
> + {
> +#ifdef _GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS
> + return __fw(__v + 0.5 * __delta);
> +#else
> + return _RealType(__fw(__v + _RealType(0.5) * __delta));
> +#endif
> + };
> +
> if (__n == 1)
> {
> _RealType __ints[2] = { __xmin, __xmin + __delta };
> - _RealType __den = __fw(__xmin + 0.5 * __delta);
> + _CalcType __den = __cfw(__xmin);
> _M_initialize2(__ints, __den);
> return;
> }
> @@ -3095,11 +3119,26 @@ namespace __detail
>
> _M_den.reserve(__n);
> for (size_t __k = 0; __k < __nw; ++__k)
> - _M_den.push_back(__fw(_M_int[__k] + 0.5 * __delta));
> + _M_den.push_back(__cfw(_M_int[__k]));
>
> _M_configure();
> }
>
> + template<typename _RealType>
> + template<typename _AdaptedUniformRandomNumberGenerator>
> + typename piecewise_constant_distribution<_RealType>::result_type
> + piecewise_constant_distribution<_RealType>::
> + __generate_one(_AdaptedUniformRandomNumberGenerator& __aurng,
> + const param_type& __param)
> + {
> + const _CalcType __p = __aurng();
> + auto __pos = std::lower_bound(__param._M_cp.begin(),
> + __param._M_cp.end(), __p);
> + const size_t __i = __pos - __param._M_cp.begin();
> + const _CalcType __pref = __i > 0 ? __param._M_cp[__i - 1] : _CalcType(0);
> + return __param._M_int[__i] + (__p - __pref) / _CalcType(__param._M_den[__i]);
> + }
> +
> template<typename _RealType>
> template<typename _UniformRandomNumberGenerator>
> typename piecewise_constant_distribution<_RealType>::result_type
> @@ -3107,20 +3146,13 @@ namespace __detail
> operator()(_UniformRandomNumberGenerator& __urng,
> const param_type& __param)
> {
> - __detail::_Adaptor<_UniformRandomNumberGenerator, double>
> + __detail::_Adaptor<_UniformRandomNumberGenerator, _CalcType>
> __aurng(__urng);
>
> - const double __p = __aurng();
> if (__param._M_cp.empty())
> - return __p;
> -
> - auto __pos = std::lower_bound(__param._M_cp.begin(),
> - __param._M_cp.end(), __p);
> - const size_t __i = __pos - __param._M_cp.begin();
> -
> - const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
> + return __aurng();
>
> - return __param._M_int[__i] + (__p - __pref) / __param._M_den[__i];
> + return __generate_one(__aurng, __param);
> }
>
> template<typename _RealType>
> @@ -3133,29 +3165,15 @@ namespace __detail
> const param_type& __param)
> {
> __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
> - __detail::_Adaptor<_UniformRandomNumberGenerator, double>
> + __detail::_Adaptor<_UniformRandomNumberGenerator, _CalcType>
> __aurng(__urng);
>
> if (__param._M_cp.empty())
> - {
> - while (__f != __t)
> - *__f++ = __aurng();
> - return;
> - }
> -
> - while (__f != __t)
> - {
> - const double __p = __aurng();
> -
> - auto __pos = std::lower_bound(__param._M_cp.begin(),
> - __param._M_cp.end(), __p);
> - const size_t __i = __pos - __param._M_cp.begin();
> -
> - const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
> -
> - *__f++ = (__param._M_int[__i]
> - + (__p - __pref) / __param._M_den[__i]);
> - }
> + while (__f != __t)
> + *__f++ = __aurng();
> + else
> + while (__f != __t)
> + *__f++ = __generate_one(__urng, __param);
> }
>
> template<typename _RealType, typename _CharT, typename _Traits>
> @@ -3230,34 +3248,37 @@ namespace __detail
> piecewise_linear_distribution<_RealType>::param_type::
> _M_configure()
> {
> - double __sum = 0.0;
> + _CalcType __sum = 0.0;
> _M_cp.reserve(_M_int.size() - 1);
> _M_m.reserve(_M_int.size() - 1);
> for (size_t __k = 0; __k < _M_int.size() - 1; ++__k)
> {
> const _RealType __delta = _M_int[__k + 1] - _M_int[__k];
> - __sum += 0.5 * (_M_den[__k + 1] + _M_den[__k]) * __delta;
> + __sum += _CalcType(0.5)
> + * (_CalcType(_M_den[__k + 1]) + _CalcType(_M_den[__k]))
> + * __delta;
> _M_cp.push_back(__sum);
> - _M_m.push_back((_M_den[__k + 1] - _M_den[__k]) / __delta);
> + _M_m.push_back(
> + (_CalcType(_M_den[__k + 1]) - _CalcType(_M_den[__k])) / __delta);
> }
> __glibcxx_assert(__sum > 0);
>
> // Now normalize the densities...
> __detail::__normalize(_M_den.begin(), _M_den.end(), _M_den.begin(),
> __sum);
> - // ... and partial sums...
> + // ... and partial sums...
> __detail::__normalize(_M_cp.begin(), _M_cp.end(), _M_cp.begin(), __sum);
> // ... and slopes.
> __detail::__normalize(_M_m.begin(), _M_m.end(), _M_m.begin(), __sum);
>
> // Make sure the last cumulative probablility is one.
> - _M_cp[_M_cp.size() - 1] = 1.0;
> + _M_cp[_M_cp.size() - 1] = _CalcType(1);
> }
>
> template<typename _RealType>
> void
> piecewise_linear_distribution<_RealType>::param_type::
> - _M_initialize2(const _RealType* __ints, const _RealType* __dens)
> + _M_initialize2(const _RealType* __ints, const _CalcType* __dens)
> {
> if (__ints[0] == _RealType(0)
> && __ints[1] == _RealType(1)
> @@ -3288,7 +3309,7 @@ namespace __detail
>
> if (__bbegin == __bend)
> {
> - _RealType __dens[2];
> + _CalcType __dens[2];
> __dens[0] = *__wbegin;
> ++__wbegin;
> __dens[1] = *__wbegin;
> @@ -3314,9 +3335,11 @@ namespace __detail
> for (; __bbegin != __bend; ++__bbegin)
> _M_int.push_back(*__bbegin);
>
> + // _GLIBCXX_RESOLVE_LIB_DEFECTS
> + // 4052. Bogus requirements for piecewise_linear_distribution
> _M_den.reserve(_M_int.size());
> for (size_t __i = 0; __i < _M_int.size(); (void)++__i, ++__wbegin)
> - _M_den.push_back(*__wbegin);
> + _M_den.push_back(_CalcType(*__wbegin));
>
> _M_configure();
> }
> @@ -3333,7 +3356,7 @@ namespace __detail
> if (__bl.size() == 2)
> {
> const _RealType *__ints = __bl.begin();
> - _RealType __den[2];
> + _CalcType __den[2];
> __den[0] = __fw(__ints[0]);
> __den[1] = __fw(__ints[1]);
> _M_initialize2(__ints, __den);
> @@ -3343,7 +3366,7 @@ namespace __detail
> _M_int = __bl;
> _M_den.reserve(__bl.size());
> for (_RealType __b : __bl)
> - _M_den.push_back(__fw(__b));
> + _M_den.push_back(_CalcType(__fw(__b)));
> _M_configure();
> }
>
> @@ -3356,18 +3379,20 @@ namespace __detail
> const size_t __n = __nw == 0 ? 1 : __nw;
> const _RealType __delta = (__xmax - __xmin) / __n;
> const auto __cfw = [&] (_RealType __v)
> - {
> + {
> #ifdef _GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS
> - return __fw(__v + __delta);
> + return __fw(__v + __delta);
> #else
> - return __fw(__v);
> + // _GLIBCXX_RESOLVE_LIB_DEFECTS
> + // 4052. Bogus requirements for piecewise_linear_distribution
> + return _RealType(__fw(__v));
> #endif
> - };
> + };
>
> if (__n == 1)
> {
> _RealType __ints[2] = { __xmin, __xmin + __delta };
> - _RealType __dens[2];
> + _CalcType __dens[2];
> __dens[0] = __cfw(__ints[0]);
> __dens[1] = __cfw(__ints[1]);
> _M_initialize2(__ints, __dens);
> @@ -3386,39 +3411,49 @@ namespace __detail
> }
>
> template<typename _RealType>
> - template<typename _UniformRandomNumberGenerator>
> + template<typename _AdaptedUniformRandomNumberGenerator>
> typename piecewise_linear_distribution<_RealType>::result_type
> piecewise_linear_distribution<_RealType>::
> - operator()(_UniformRandomNumberGenerator& __urng,
> - const param_type& __param)
> + __generate_one(_AdaptedUniformRandomNumberGenerator& __aurng,
> + const param_type& __param)
> {
> - __detail::_Adaptor<_UniformRandomNumberGenerator, double>
> - __aurng(__urng);
> -
> - const double __p = __aurng();
> - if (__param._M_cp.empty())
> - return __p;
> -
> + const _CalcType __p = __aurng();
> auto __pos = std::lower_bound(__param._M_cp.begin(),
> __param._M_cp.end(), __p);
> const size_t __i = __pos - __param._M_cp.begin();
>
> - const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
> + const _CalcType __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0;
>
> - const double __a = 0.5 * __param._M_m[__i];
> - const double __b = __param._M_den[__i];
> - const double __cm = __p - __pref;
> + const _CalcType __a = _CalcType(0.5) * __param._M_m[__i];
> + const _CalcType __b = __param._M_den[__i];
> + const _CalcType __cm = __p - __pref;
>
> _RealType __x = __param._M_int[__i];
> if (__a == 0)
> __x += __cm / __b;
> else
> {
> - const double __d = __b * __b + 4.0 * __a * __cm;
> - __x += 0.5 * (std::sqrt(__d) - __b) / __a;
> - }
> + const _CalcType __d = __b * __b + 4.0 * __a * __cm;
> + __x += _CalcType(0.5) * (std::sqrt(__d) - __b) / __a;
> + }
> + return __x;
> + }
> +
>
> - return __x;
> + template<typename _RealType>
> + template<typename _UniformRandomNumberGenerator>
> + typename piecewise_linear_distribution<_RealType>::result_type
> + piecewise_linear_distribution<_RealType>::
> + operator()(_UniformRandomNumberGenerator& __urng,
> + const param_type& __param)
> + {
> + __detail::_Adaptor<_UniformRandomNumberGenerator, _CalcType>
> + __aurng(__urng);
> +
> + if (__param._M_cp.empty())
> + return __aurng();
> +
> + return __generate_one(__aurng, __param);
> }
>
> template<typename _RealType>
> @@ -3431,9 +3466,15 @@ namespace __detail
> const param_type& __param)
> {
> __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>)
> - // We could duplicate everything from operator()...
> - while (__f != __t)
> - *__f++ = this->operator()(__urng, __param);
> + __detail::_Adaptor<_UniformRandomNumberGenerator, _CalcType>
> + __aurng(__urng);
> +
> + if (__param._M_cp.empty())
> + while (__f != __t)
> + *__f++ = __aurng();
> + else
> + while (__f != __t)
> + *__f++ = __generate_one(__urng, __param);
> }
>
> template<typename _RealType, typename _CharT, typename _Traits>
> diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/input_type.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/input_type.cc
> new file mode 100644
> index 00000000000..ebd548eb5c4
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/input_type.cc
> @@ -0,0 +1,52 @@
> +// { dg-do compile { target c++11 } }
> +// { dg-require-cstdint "" }
> +
> +#include <random>
> +
> +template<typename RealType>
> +struct OnlyConv
> +{
> + long double v;
> +
> + template<typename DestType>
> + operator DestType() const
> + {
> + static_assert(std::is_same<DestType, RealType>::value);
> + return v;
> + }
> +};
> +
> +template<typename RealType>
> +struct OnlyCall
> +{
> + template<typename SourceType>
> + OnlyConv<RealType> operator()(SourceType src)
> + {
> + static_assert(std::is_same<SourceType, RealType>::value);
> + return OnlyConv<RealType>{src};
> + }
> +};
> +
> +template<typename RealType>
> +void
> +test()
> +{
> + std::initializer_list<RealType> invs{0, 1, 2};
> + OnlyConv<RealType> weights[2]{1, 2};
> +
> + std::piecewise_constant_distribution<RealType>
> + from_iter(invs.begin(), invs.end(), weights);
> +
> + std::piecewise_constant_distribution<RealType>
> + from_init_list(invs, OnlyCall<RealType>());
> +
> + std::piecewise_constant_distribution<RealType>
> + from_count(2, 0, 2, OnlyCall<RealType>());
> +}
> +
> +int main()
> +{
> + test<float>();
> + test<double>();
> + test<long double>();
> +}
> diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/input_type_fallback_neg.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/input_type_fallback_neg.cc
> new file mode 100644
> index 00000000000..6fb04ef7655
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/input_type_fallback_neg.cc
> @@ -0,0 +1,55 @@
> +// { dg-options "-D_GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS" }
> +// { dg-do compile { target c++11 } }
> +// { dg-require-cstdint "" }
> +
> +#include <random>
> +
> +template<typename RealType>
> +struct OnlyConv
> +{
> + long double v;
> +
> + template<typename DestType>
> + operator DestType() const
> + {
> + static_assert(std::is_same<DestType, RealType>::value);
> + return v;
> + }
> +};
> +
> +template<typename RealType>
> +struct OnlyCall
> +{
> + template<typename SourceType>
> + OnlyConv<RealType> operator()(SourceType src)
> + {
> + static_assert(std::is_same<SourceType, RealType>::value);
> + return OnlyConv<RealType>{src};
> + }
> +};
> +
> +template<typename RealType>
> +void
> +test()
> +{
> + std::initializer_list<RealType> invs{0, 1, 2};
> + OnlyConv<RealType> weights[2]{1, 2};
> +
> + std::piecewise_constant_distribution<RealType>
> + from_iter(invs.begin(), invs.end(), weights);
> +
> + std::piecewise_constant_distribution<RealType>
> + from_init_list(invs, OnlyCall<RealType>());
> +
> + std::piecewise_constant_distribution<RealType>
> + from_count(2, 0, 2, OnlyCall<RealType>());
> +}
> +
> +int main()
> +{
> + test<float>(); // { dg-error "here" }
> + test<double>();
> + test<long double>(); // { dg-error "here" }
> +}
> +
> +// { dg-prune-output "static assertion failed" }
> 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
> index db4193847e3..15fb6821749 100644
> --- 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
> @@ -33,39 +33,84 @@ test_exact()
> VERIFY( density[4] == RealType(0.5 / 8.0) );
> }
>
> -template<typename RealType>
> +template<typename InputType, typename DistType = InputType>
> void
> test_precision_depended()
> {
> constexpr bool preserved
> -#ifdef _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES
> - = true;
> +#ifdef _GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS
> + = sizeof(InputType) <= sizeof(double);
> +#elifdef _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES
> + = sizeof(InputType) <= sizeof(DistType);
> #else
> - = sizeof(RealType) <= sizeof(double);
> + // input is converted to DistType and stored in double
> + = (sizeof(InputType) <= sizeof(DistType))
> + && (sizeof(InputType) <= 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::initializer_list<DistType> x{0.0, 0.5, 1.0};
> + constexpr InputType step
> + = std::numeric_limits<InputType>::epsilon();
> + InputType wt[2]{InputType(1) - step, InputType(1) + step};
>
> - std::piecewise_constant_distribution<RealType>
> - u(std::begin(x), std::end(x), wt);
> + using Distribution = std::piecewise_constant_distribution<DistType>;
> + auto validate = [&wt](const Distribution& dist)
> + {
> + const std::vector<DistType>& interval = dist.intervals();
> + VERIFY( interval.size() == 3 );
> + VERIFY( interval[0] == DistType(0.0) );
> + VERIFY( interval[2] == DistType(1.0) );
>
> - 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_PIECEWISE_DISTRIBUTIONS
> + const std::vector<double>& density = dist.densities();
> +#else
> + const std::vector<DistType>& density = dist.densities();
> +#endif
> +
> + VERIFY( density.size() == 2 );
> + VERIFY( density[0] == (preserved ? wt[0] : InputType(1)) );
> + VERIFY( density[1] == (preserved ? wt[1] : InputType(1)) );
> + };
> +
> + Distribution from_iter(x.begin(), x.end(), wt);
> + validate(from_iter);
>
> + auto wf = [&wt](DistType v)
> + { return wt[int(v / 0.5)]; };
> +
> + Distribution from_init_list(x, wf);
> + validate(from_init_list);
> +
> + Distribution from_count(2, InputType(0), InputType(1), wf);
> + validate(from_count);
> +}
> +
> +template<typename RealType, typename URBG = std::mt19937>
> +void
> +test_engine_calls()
> +{
> + constexpr std::size_t bits = __builtin_popcountg(URBG::max() - URBG::min());
> + constexpr std::size_t calls
> #ifdef _GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS
> - const std::vector<double>& density = u.densities();
> + = (std::numeric_limits<double>::digits + bits - 1) / bits;
> #else
> - const std::vector<RealType>& density = u.densities();
> + = (std::numeric_limits<RealType>::digits + bits - 1) / bits;
> #endif
>
> - VERIFY( density.size() == 2 );
> - VERIFY( density[0] == (preserved ? wt[0] : RealType(1)) );
> - VERIFY( density[1] == (preserved ? wt[1] : RealType(1)) );
> + struct wrapper : URBG
> + {
> + typename URBG::result_type operator()()
> + {
> + ++num_calls;
> + return URBG::operator()();
> + }
> + std::size_t num_calls = 0;
> + };
> +
> + wrapper eng;
> + std::piecewise_constant_distribution<RealType> u;
> + u(eng);
> + VERIFY(eng.num_calls == calls);
> }
>
> int main()
> @@ -79,5 +124,12 @@ int main()
> test_precision_depended<double>();
> test_precision_depended<long double>();
>
> + test_precision_depended<double, float>();
> + test_precision_depended<long double, float>();
> + test_precision_depended<long double, double>();
> +
> + test_engine_calls<float>();
> + test_engine_calls<double>();
> + test_engine_calls<long double>();
> return 0;
> }
> diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/serialize2.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/serialize2.cc
> index 60838d7396b..dae9f4aaf34 100644
> --- a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/serialize2.cc
> +++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/serialize2.cc
> @@ -38,7 +38,7 @@ test_default()
> "1 0.00000000000000000e+00 1.00000000000000000e+00 1.00000000000000000e+00";
> VERIFY( res == expected );
> break;
> - case 64: // ieee80
> + case 64: // ieee80
> expected =
> "1 0.000000000000000000000e+00 1.000000000000000000000e+00 1.000000000000000000000e+00";
> VERIFY( res == expected );
> @@ -74,19 +74,19 @@ test_custom()
> case 24: // ieee32
> expected =
> "3 0.000000000e+00 3.333333433e-01 6.666666865e-01 1.000000000e+00"
> - " 7.777777281e-01 9.999999702e-01 1.222222322e+00";
> + " 7.777777314e-01 1.000000000e+00 1.222222328e+00";
> VERIFY( res == expected );
> break;
> case 53: // ieee64
> expected =
> "3 0.00000000000000000e+00 3.33333333333333315e-01 6.66666666666666630e-01 1.00000000000000000e+00"
> - " 7.77777777777777901e-01 1.00000000000000000e+00 1.22222222222222210e+00";
> + " 7.77777777777777901e-01 1.00000000000000000e+00 1.22222222222222210e+00";
> VERIFY( res == expected );
> break;
> - case 64: // ieee80
> + case 64: // ieee80
> expected =
> "3 0.000000000000000000000e+00 3.333333333333333333424e-01 6.666666666666666666847e-01 1.000000000000000000000e+00"
> - " 7.777777777777779011359e-01 1.000000000000000000000e+00 1.222222222222222098864e+00";
> + " 7.777777777777779011359e-01 1.000000000000000000000e+00 1.222222222222222098864e+00";
> VERIFY( res == expected );
> break;
> default:
> diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/input_type.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/input_type.cc
> new file mode 100644
> index 00000000000..3c5b717e0f2
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/input_type.cc
> @@ -0,0 +1,52 @@
> +// { dg-do compile { target c++11 } }
> +// { dg-require-cstdint "" }
> +
> +#include <random>
> +
> +template<typename RealType>
> +struct OnlyConv
> +{
> + long double v;
> +
> + template<typename DestType>
> + operator DestType() const
> + {
> + static_assert(std::is_same<DestType, RealType>::value);
> + return v;
> + }
> +};
> +
> +template<typename RealType>
> +struct OnlyCall
> +{
> + template<typename SourceType>
> + OnlyConv<RealType> operator()(SourceType src)
> + {
> + static_assert(std::is_same<SourceType, RealType>::value);
> + return OnlyConv<RealType>{src};
> + }
> +};
> +
> +template<typename RealType>
> +void
> +test()
> +{
> + std::initializer_list<RealType> invs{0, 1, 2};
> + OnlyConv<RealType> weights[3]{1, 2, 3};
> +
> + std::piecewise_linear_distribution<RealType>
> + from_iter(invs.begin(), invs.end(), weights);
> +
> + std::piecewise_linear_distribution<RealType>
> + from_init_list(invs, OnlyCall<RealType>());
> +
> + std::piecewise_linear_distribution<RealType>
> + from_count(2, 0, 2, OnlyCall<RealType>());
> +}
> +
> +int main()
> +{
> + test<float>();
> + test<double>();
> + test<long double>();
> +}
> diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/input_type_fallback_neg.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/input_type_fallback_neg.cc
> new file mode 100644
> index 00000000000..48ae22b87bb
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/input_type_fallback_neg.cc
> @@ -0,0 +1,55 @@
> +// { dg-options "-D_GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS" }
> +// { dg-do compile { target c++11 } }
> +// { dg-require-cstdint "" }
> +
> +#include <random>
> +
> +template<typename RealType>
> +struct OnlyConv
> +{
> + long double v;
> +
> + template<typename DestType>
> + operator DestType() const
> + {
> + static_assert(std::is_same<DestType, RealType>::value);
> + return v;
> + }
> +};
> +
> +template<typename RealType>
> +struct OnlyCall
> +{
> + template<typename SourceType>
> + OnlyConv<RealType> operator()(SourceType src)
> + {
> + static_assert(std::is_same<SourceType, RealType>::value);
> + return OnlyConv<RealType>{src};
> + }
> +};
> +
> +template<typename RealType>
> +void
> +test()
> +{
> + std::initializer_list<RealType> invs{0, 1, 2};
> + OnlyConv<RealType> weights[3]{1, 2, 3};
> +
> + std::piecewise_linear_distribution<RealType>
> + from_iter(invs.begin(), invs.end(), weights);
> +
> + std::piecewise_linear_distribution<RealType>
> + from_init_list(invs, OnlyCall<RealType>());
> +
> + std::piecewise_linear_distribution<RealType>
> + from_count(2, 0, 2, OnlyCall<RealType>());
> +}
> +
> +int main()
> +{
> + test<float>(); // { dg-error "here" }
> + test<double>();
> + test<long double>(); // { dg-error "here" }
> +}
> +
> +// { dg-prune-output "static assertion failed" }
> 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
> index 0a13e0fd9e2..5da22fc1011 100644
> --- 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
> @@ -34,40 +34,88 @@ test_exact()
> VERIFY( density[5] == RealType(2.0 / 8.0) );
> }
>
> -template<typename RealType>
> +template<typename InputType, typename DistType = InputType>
> void
> test_precision_depended()
> {
> constexpr bool preserved
> -#ifdef _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES
> - = true;
> +#ifdef _GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS
> + = sizeof(InputType) <= sizeof(double);
> +#elifdef _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES
> + = sizeof(InputType) <= sizeof(DistType);
> #else
> - = sizeof(RealType) <= sizeof(double);
> + // input is converted to DistType and stored in double
> + = (sizeof(InputType) <= sizeof(DistType))
> + && (sizeof(InputType) <= 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::initializer_list<DistType> x{0.0, 0.5, 1.0};
> + constexpr InputType step
> + = std::numeric_limits<InputType>::epsilon() * 2;
> + InputType wt[3]{InputType(1) - step, InputType(1), InputType(1) + step};
>
> - std::piecewise_linear_distribution<RealType>
> - u(std::begin(x), std::end(x), wt);
> + using Distribution = std::piecewise_linear_distribution<DistType>;
> + auto validate = [&wt](const Distribution& dist)
> + {
> + const std::vector<DistType>& interval = dist.intervals();
> + VERIFY( interval.size() == 3 );
> + VERIFY( interval[0] == DistType(0.0) );
> + VERIFY( interval[2] == DistType(1.0) );
>
> - 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_PIECEWISE_DISTRIBUTIONS
> + const std::vector<double>& density = dist.densities();
> +#else
> + const std::vector<DistType>& density = dist.densities();
> +#endif
> +
> + VERIFY( density.size() == 3 );
> + VERIFY( density[0] == (preserved ? wt[0] : InputType(1)) );
> + VERIFY( density[1] == InputType(1) );
> + VERIFY( density[2] == (preserved ? wt[2] : InputType(1)) );
> + };
> +
> + Distribution from_iter(x.begin(), x.end(), wt);
> + validate(from_iter);
>
> + auto wf = [&wt](DistType v)
> + { return wt[int(v / 0.5)]; };
> +
> + Distribution from_init_list(x, wf);
> + validate(from_init_list);
> +
> +#ifndef _GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS
> + // PR125548 leads to incorrect densities being used
> + Distribution from_count(2, InputType(0), InputType(1), wf);
> + validate(from_count);
> +#endif
> +}
> +
> +template<typename RealType, typename URBG = std::mt19937>
> +void
> +test_engine_calls()
> +{
> + constexpr std::size_t bits = __builtin_popcountg(URBG::max() - URBG::min());
> + constexpr std::size_t calls
> #ifdef _GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS
> - const std::vector<double>& density = u.densities();
> + = (std::numeric_limits<double>::digits + bits - 1) / bits;
> #else
> - const std::vector<RealType>& density = u.densities();
> + = (std::numeric_limits<RealType>::digits + bits - 1) / bits;
> #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)) );
> + struct wrapper : URBG
> + {
> + typename URBG::result_type operator()()
> + {
> + ++num_calls;
> + return URBG::operator()();
> + }
> + std::size_t num_calls = 0;
> + };
> +
> + wrapper eng;
> + std::piecewise_linear_distribution<RealType> u;
> + u(eng);
> + VERIFY(eng.num_calls == calls);
> }
>
> int main()
> @@ -81,5 +129,12 @@ int main()
> test_precision_depended<double>();
> test_precision_depended<long double>();
>
> + test_precision_depended<double, float>();
> + test_precision_depended<long double, float>();
> + test_precision_depended<long double, double>();
> +
> + test_engine_calls<float>();
> + test_engine_calls<double>();
> + test_engine_calls<long double>();
> return 0;
> }
> diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/serialize2.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/serialize2.cc
> index 21365057f9e..55f0d8c427d 100644
> --- a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/serialize2.cc
> +++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/serialize2.cc
> @@ -24,7 +24,7 @@ test_default()
>
> if (!std::numeric_limits<RealType>::is_iec559)
> return;
> -
> +
> char const* expected = nullptr;
> switch (std::numeric_limits<RealType>::digits)
> {
> @@ -40,7 +40,7 @@ test_default()
> " 1.00000000000000000e+00 1.00000000000000000e+00";
> VERIFY( res == expected );
> break;
> - case 64: // ieee80
> + case 64: // ieee80
> expected =
> "1 0.000000000000000000000e+00 1.000000000000000000000e+00"
> " 1.000000000000000000000e+00 1.000000000000000000000e+00";
> @@ -63,7 +63,7 @@ test_custom()
> str << u;
> std::string res = str.str();
>
> - std::piecewise_constant_distribution<RealType> v;
> + std::piecewise_linear_distribution<RealType> v;
> str >> v;
> // This does not hold currently
> // VERIFY( u == v );
> @@ -77,16 +77,16 @@ test_custom()
> case 24: // ieee32
> expected =
> "3 0.000000000e+00 3.333333433e-01 6.666666865e-01 1.000000000e+00"
> - " 6.666666534e-01 8.888888977e-01 1.111111142e+00 1.333333307e+00";
> + " 6.666666865e-01 8.888888955e-01 1.111111164e+00 1.333333373e+00";
> VERIFY( res == expected );
> break;
> case 53: // ieee64
> expected =
> - "3 0.00000000000000000e+00 3.33333333333333315e-01 6.66666666666666630e-01 1.00000000000000000e+00"
> + "3 0.00000000000000000e+00 3.33333333333333315e-01 6.66666666666666630e-01 1.00000000000000000e+00"
> " 6.66666666666666630e-01 8.88888888888888840e-01 1.11111111111111094e+00 1.33333333333333326e+00";
> VERIFY( res == expected );
> break;
> - case 64: // ieee80
> + case 64: // ieee80
> expected =
> "3 0.000000000000000000000e+00 3.333333333333333333424e-01 6.666666666666666666847e-01 1.000000000000000000000e+00"
> " 6.666666666666666296592e-01 8.888888888888888395456e-01 1.111111111111111160454e+00 1.333333333333333259318e+00";
> @@ -103,10 +103,9 @@ int main()
> test_default<double>();
> test_default<long double>();
>
> -#ifdef __x86_64__
> test_custom<float>();
> test_custom<double>();
> -#endif
> test_custom<long double>();
> +
> return 0;
> }
> --
> 2.55.0
>
More information about the Libstdc++
mailing list