On Mon, Jun 1, 2026 at 10:16 AM Jonathan Wakely <[email protected]> wrote:

> On Mon, 1 Jun 2026 at 08:24, Tomasz Kamiński <[email protected]> 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
>
> This macro is spelled PICEWISE everywhere (in the commit message, the
> docs, and the code) instead of PIECEWISE.
>
> I haven't reviewed it properly yet, just noting that for now.
>
>
> > 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.
> > +      </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;
>
While fixing the name, I noticed I have this change locally, but it wasn't
included in the email.
   namespace __detail
   {
-#ifdef _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES
+#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.
> >     *
> > @@ -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
> >
>
>

Reply via email to