On Mon, 01 Jun 2026 at 09:21 +0200, Tomasz Kamiński wrote:
This implements the interface changes from
LWG1439, "Return from densities() functions?".

Due the ABI concerns, we cannot change the the element_type of member
(_M_den, _M_cp, and _M_m) vectors, and we convert the _M_den values
to result_type when function is invoked. However, as the usage of
distributions with types other than float, double, and long double
is either undefined (pre C++26) or implementaiton-defined (post C++26),
this limitation de-fact applies to float, and long double (if it's
different size than double).

To handle above we introduce the __piecewise_distributions_storage<_Tp>
struct, whose type nested typedef points to double in above two cases,
and _Tp otherwise. The _StorageType is defined in terms of
__piecewise_distributions_storage_t alias to above, and is then used
in defintion of _M_den, _M_cp, and _M_m members. In consequence for
extended floating point types (__float128, std::float16, ...) for which
ABI can be changed, we store densitiees (and other values) as result_type.

To avoid symbol conflicts, the param_type::densities member functions
are marked with "__rt" ABI tag. The corresponding members of the
distributions are modified to invoke param_type method, and marked
as always_inline. For consistency intervals methods are adjusted same
way.

To preserve current behavior, the operators>> load densities
as values of _StorageType.

Finally, we introduce _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS, that
revers above changes, restoring old behavior for all floating point
types. Additionally for the users accept above ABI change,
we introduce a macro _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES,
that result in __piecewise_distributions_storage_t being unconditionally
defined as _Tp, and thus adjust internal storage also for float and long
double.

        libstdc++ PR/82749

libstdc++-v3/ChangeLog:

        * doc/xml/manual/using.xml
        (_GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS): Add entry.
        (_GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES): Add entry.
        * doc/html/manual/using_macros.html: Regenerate.
        * include/bits/random.h
        (__detail::__piecewise_distributions_storage)
        (__detail::__piecewise_distributions_storage_t)
        (piecewise_constant_distribution::_StorageType)
        (piecewise_linear_distribution::_StorageType): Define.
        (piecewise_constant_distribution::param_type::_M_den)
        (piecewise_constant_distribution::param_type::_M_cp)
        (piecewise_linear_distribution::param_type::_M_den)
        (piecewise_linear_distribution::param_type::_M_cp)
        (piecewise_linear_distribution::param_type::_M_m): Use _StorageType
        as element type.
        (piecewise_constant_distribution::param_type::densities)
        (piecewise_linear_distribution::param_type::densities)
        [!_GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS]: Change return type
        to vector<result_type>, mark with "__rt" ABI tag, and adjust
        implementation.
        (piecewise_constant_distribution::param_type::intervals)
        (piecewise_linear_distribution::param_type::intervals): Use
        result_type alias in return type.
        (piecewise_constant_distribution::densities)
        (piecewise_linear_distribution::densities): Delegate to param_type
        method, additional change return type and  mark as always_inline
        if _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS is not defined.
        (piecewise_constant_distribution::intervals)
        (piecewise_linear_distribution::intervals): Delegate to param_type
        method and use result_type alias in return type.
        * include/bits/random.tcc
        (operator<<(basic_ostream&, const piecewise_constant_distribution&))
        (operator<<(basic_ostream&, const piecewise_linear_distribution&)):
        Parse vector of _StorageType for densities, to preserve behavior.
        * 
testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors.cc:
        New test.
        * 
testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors.cc:
        New test.
        * 
testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors_exact.cc:
        Run accessors.cc with _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES.
        * 
testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors_exact.cc:
        Likewise.
        * 
testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors_fallback.cc:
        Run accessors.cc with _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS.
        * 
testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors_fallback.cc:
        Likewise.
---
v2 adds also _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS, that
reverts the changes. I plan to use it for all changes made
to this distributions in GCC-17.
Additionally
* updates and add PR link to commit description
* add accessorrs_fallback.cc tests
* use result_type in return consistently on new path

Resated *piecewise* test. Testing on x86_64-linux.
OK for trunk?

.../doc/html/manual/using_macros.html         |  19 +++
libstdc++-v3/doc/xml/manual/using.xml         |  29 ++++
libstdc++-v3/include/bits/random.h            | 154 +++++++++++++-----
libstdc++-v3/include/bits/random.tcc          |   8 +-
.../operators/accessors.cc                    |  83 ++++++++++
.../operators/accessors_exact.cc              |   5 +
.../operators/accessors_fallback.cc           |   5 +
.../operators/accessors.cc                    |  85 ++++++++++
.../operators/accessors_exact.cc              |   5 +
.../operators/accessors_fallback.cc           |   5 +
10 files changed, 359 insertions(+), 39 deletions(-)
create mode 100644 
libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors.cc
create mode 100644 
libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors_exact.cc
create mode 100644 
libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/operators/accessors_fallback.cc
create mode 100644 
libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors.cc
create mode 100644 
libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors_exact.cc
create mode 100644 
libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/operators/accessors_fallback.cc

diff --git a/libstdc++-v3/doc/html/manual/using_macros.html 
b/libstdc++-v3/doc/html/manual/using_macros.html
index f1d8492fb9e..4be2ab576dc 100644
--- a/libstdc++-v3/doc/html/manual/using_macros.html
+++ b/libstdc++-v3/doc/html/manual/using_macros.html
@@ -156,4 +156,23 @@
        <code class="option">-fexec-charset=UTF-8</code> so might give 
incorrect results
        if called from a source file that uses a non-Unicode encoding,
        especially for format strings using non-ASCII fill characters.
+      </p></dd><dt><span class="term"><code 
class="code">_GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS</code></span></dt><dd><p>
+       Undefined by default.
+       When defined, the behaviour specializations of

The grammar seems garbled here, "the behaviour specializations of foo
and bar their behavior to the state prior to the implementation of
..."

Also, two different spellings of "behaviour". The manual pages usually
use the American spelling, "behavior" (there are a few places that
were probably written by me and use the British spelling).

+       <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

Period at the end of the sentence.

      </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="using_headers.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="using.html">Up</a></td><td width="40%" align="right"> 
<a accesskey="n" href="using_dual_abi.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Headers </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Dual ABI</td></tr></table></div></body></html>
\ No newline at end of file
diff --git a/libstdc++-v3/doc/xml/manual/using.xml 
b/libstdc++-v3/doc/xml/manual/using.xml
index e2e75e8fe28..1759eb5a214 100644
--- a/libstdc++-v3/doc/xml/manual/using.xml
+++ b/libstdc++-v3/doc/xml/manual/using.xml
@@ -1379,6 +1379,35 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 
hello.cc -o test.exe
        especially for format strings using non-ASCII fill characters.
      </para>
    </listitem></varlistentry>
+    
<varlistentry><term><code>_GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS</code></term>
+     <listitem>
+      <para>
+       Undefined by default.
+       When defined, the behaviour specializations of
+       <code>piecewise_constant_distribution</code> and
+       <code>piecewise_linear_distribution</code> for
+       their behavior to the state prior the implementation
+       of <link xmlns:xlink="http://www.w3.org/1999/xlink";
+       xlink:href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82749";>
+       PR82749</link> (<link xmlns:xlink="http://www.w3.org/1999/xlink";
+       xlink:href="https://cplusplus.github.io/LWG/lwg-defects.html#1439";>
+       LWG1439</link>) in GCC-17.
+      </para>
+    </listitem></varlistentry>
+    
<varlistentry><term><code>_GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES</code></term>
+    <listitem>
+      <para>
+       Undefined by default. ABI-changing.
+       When defined, specializations of
+       <code>piecewise_constant_distribution</code> and
+       <code>piecewise_linear_distribution</code> with a
+       <code>result_type</code> of either <code>float</code> or
+       <code>long double</code> will manage their internal state using
+       <code>result_type</code> values (instead of <code>double</code>).
+       This is required for standard conformance, but is incompatible with
+       the default implementation of those class templates
+      </para>
+    </listitem></varlistentry>
    </variablelist>

  </section>
diff --git a/libstdc++-v3/include/bits/random.h 
b/libstdc++-v3/include/bits/random.h
index a0592a00763..6b82d1120b7 100644
--- a/libstdc++-v3/include/bits/random.h
+++ b/libstdc++-v3/include/bits/random.h
@@ -6385,6 +6385,40 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
    { return !(__d1 == __d2); }
#endif

+  namespace __detail
+  {
+#ifdef _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES
+    template<typename _Tp>
+      using __piecewise_distributions_storage_t = _Tp;
+#else
+    template<typename _Tp>
+      struct __piecewise_distributions_storage
+      { using type = _Tp; };
+
+    template<>
+      struct __piecewise_distributions_storage<float>
+      { using type = double; };
+
+# ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+    template<>
+      struct __piecewise_distributions_storage<__ibm128>
+      { using type = double; };
+
+    template<>
+      struct __piecewise_distributions_storage<__ieee128>
+      { using type = double; };
+# elif __LDBL_MANT_DIG__ != __DBL_MANT_DIG__
+    template<>
+      struct __piecewise_distributions_storage<long double>
+      { using type = double; };
+# endif
+
+    template<typename _Tp>
+       using __piecewise_distributions_storage_t
+       = typename __piecewise_distributions_storage<_Tp>::type;
+#endif // _GLIBCXX_USE_RESULT_TYPE_FOR_PIECEWISE_DENSITIES
+  }
+
  /**
   * @brief A piecewise_constant_distribution random number distribution.
   *
@@ -6407,6 +6441,9 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
      static_assert(std::is_floating_point<_RealType>::value,
                    "result_type must be a floating point type");

+      using _StorageType
+       = __detail::__piecewise_distributions_storage_t<_RealType>;
+
    public:
      /** The type of the range of the distribution. */
      typedef _RealType result_type;
@@ -6437,7 +6474,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
        param_type(const param_type&) = default;
        param_type& operator=(const param_type&) = default;

-       std::vector<_RealType>
+       std::vector<result_type>
        intervals() const
        {
          if (_M_int.empty())
@@ -6450,9 +6487,34 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
            return _M_int;
        }

+#ifdef _GLIBCXX_USE_OLD_PICEWISE_DISTRIBUTIONS
        std::vector<double>
        densities() const
        { return _M_den.empty() ? std::vector<double>(1, 1.0) : _M_den; }
+#else
+       // _GLIBCXX_RESOLVE_LIB_DEFECTS
+       // 1439. Return from densities() functions?
+       [[__gnu__::__abi_tag__("__rt")]]

I've been trying to think of a tag name that is a bit more
self-documenting that "rt" but I don't have a better suggestion.

+       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;

Can this be simply return {_M_den.begin(), _M_den.end()} ?
That will convert from _StorageType to _RealType.

+           }
+#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