[PATCH v2] libstdc++: Change piecewise distribution densities to return vector<result_type> [PR82749]
Jonathan Wakely
jwakely@redhat.com
Tue Jul 14 09:03:36 GMT 2026
On Tue, 14 Jul 2026 at 08:07, Tomasz Kamiński <tkaminsk@redhat.com> 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.
> ---
> changes in v2:
> * reworked description of _GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS,
> including spelling of "behavior" and "GCC 17"
> * add missing dot for _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES
> * use std::vector<_RealType>(_M_den.begin(), _M_den.end()) to conver
> the densities
> The std qualification for vector is prevalent in this file, so kept
> it for consistency.
I think that's because most of the code in <random> originated in
<tr1/random> and we qualified things from std within std::tr1. It's
vestigial now, but consistency is good. We can clean it all up some
time, but not in this patch.
>
> Testing on x86_64-linux. Retested *piecewise* test will all standards,
> debug/-m32. OK for trunk?
>
> .../doc/html/manual/using_macros.html | 19 +++
> libstdc++-v3/doc/xml/manual/using.xml | 29 ++++
> libstdc++-v3/include/bits/random.h | 145 +++++++++++++-----
> 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, 350 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..4febcdbd1de 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_PIECEWISE_DISTRIBUTIONS</code></span></dt><dd><p>
> + Undefined by default.
> + When defined, the behavior specializations of
Please add "of" after behavior.
OK for trunk with that tweak.
> + <code class="code">piecewise_constant_distribution</code> and
> + <code class="code">piecewise_linear_distribution</code>
> + 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>) 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.
> + 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..63f24f56bc2 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_PIECEWISE_DISTRIBUTIONS</code></term>
> + <listitem>
> + <para>
> + Undefined by default.
> + When defined, the behavior specializations of
> + <code>piecewise_constant_distribution</code> and
> + <code>piecewise_linear_distribution</code>
> + is restored to their 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 fd7b8b4fb20..c219930cc29 100644
> --- a/libstdc++-v3/include/bits/random.h
> +++ b/libstdc++-v3/include/bits/random.h
> @@ -6409,6 +6409,43 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
> { return !(__d1 == __d2); }
> #endif
>
> + namespace __detail
> + {
> +#if defined(_GLIBCXX_USE_OLD_PIECEWISE_DISTRIBUTIONS)
> + template<typename _Tp>
> + using __piecewise_distributions_storage_t = double;
> +#elif defined(_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.
> *
> @@ -6431,6 +6468,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;
> @@ -6461,7 +6501,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())
> @@ -6474,9 +6514,28 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
> return _M_int;
> }
>
> +#ifdef _GLIBCXX_USE_OLD_PIECEWISE_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
> + return std::vector<_RealType>(_M_den.begin(), _M_den.end());
> +#pragma GCC diagnostic pop
> + }
> +#endif
>
> friend bool
> operator==(const param_type& __p1, const param_type& __p2)
> @@ -6496,8 +6555,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>&
> @@ -6544,28 +6603,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_PIECEWISE_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.
> @@ -6719,6 +6773,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;
> @@ -6749,7 +6806,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())
> @@ -6762,9 +6819,28 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
> return _M_int;
> }
>
> +#ifdef _GLIBCXX_USE_OLD_PIECEWISE_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
> + return std::vector<_RealType>(_M_den.begin(), _M_den.end());
> +#pragma GCC diagnostic pop
> + }
> +#endif
>
> friend bool
> operator==(const param_type& __p1, const param_type& __p2)
> @@ -6784,9 +6860,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>&
> @@ -6833,29 +6909,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_PIECEWISE_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 a8fab79961d..12c891fbbaf 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..db4193847e3
> --- /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_PIECEWISE_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_PIECEWISE_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..1f7269a879c
> --- /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_PIECEWISE_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..0a13e0fd9e2
> --- /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_PIECEWISE_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_PIECEWISE_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..1f7269a879c
> --- /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_PIECEWISE_DISTRIBUTIONS" }
> +// { dg-do run { target c++11 } }
> +// { dg-require-cstdint "" }
> +#include "accessors.cc"
> +
> --
> 2.54.0
>
More information about the Libstdc++
mailing list