https://gcc.gnu.org/g:33ac889aa27d9917e6e7d07c282015b7c48e0440

commit r17-901-g33ac889aa27d9917e6e7d07c282015b7c48e0440
Author: Tomasz Kamiński <[email protected]>
Date:   Mon May 25 15:15:09 2026 +0200

    libstdc++: Optimize operator<< for piecewise distributions.
    
    This avoids creating an temporary vector and uses _M_int and _M_den
    members of _M_param. Empty _M_int (default) values are handled by
    printing values direclty.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/random.h 
(piecewise_constant_distribution::param_type)
            (piecewise_linear_distribution::param_type): Befriend operator<<.
            * include/bits/random.tcc
            (operator<<(basic_ostream&, piecewise_linear_distribution))
            (operator<<(basic_ostream&, piecewise_constant_distribution)):
            Use __x._M_param._M_int and __x._M_param._M_den instead of 
accessors.
    
    Reviewed-by: Jonathan Wakely <[email protected]>
    Signed-off-by: Tomasz Kamiński <[email protected]>

Diff:
---
 libstdc++-v3/include/bits/random.h   | 10 ++++++++
 libstdc++-v3/include/bits/random.tcc | 44 +++++++++++++++++++++---------------
 2 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/libstdc++-v3/include/bits/random.h 
b/libstdc++-v3/include/bits/random.h
index 5d037465d3cf..a0592a007634 100644
--- a/libstdc++-v3/include/bits/random.h
+++ b/libstdc++-v3/include/bits/random.h
@@ -6474,6 +6474,11 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
        std::vector<_RealType> _M_int;
        std::vector<double> _M_den;
        std::vector<double> _M_cp;
+
+       template<typename _RealType1, typename _CharT, typename _Traits>
+         friend std::basic_ostream<_CharT, _Traits>&
+         operator<<(std::basic_ostream<_CharT, _Traits>&,
+                    const std::piecewise_constant_distribution<_RealType1>&);
       };
 
       piecewise_constant_distribution()
@@ -6758,6 +6763,11 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
        std::vector<double> _M_den;
        std::vector<double> _M_cp;
        std::vector<double> _M_m;
+
+       template<typename _RealType1, typename _CharT, typename _Traits>
+         friend std::basic_ostream<_CharT, _Traits>&
+         operator<<(std::basic_ostream<_CharT, _Traits>&,
+                    const std::piecewise_linear_distribution<_RealType1>&);
       };
 
       piecewise_linear_distribution()
diff --git a/libstdc++-v3/include/bits/random.tcc 
b/libstdc++-v3/include/bits/random.tcc
index 80b51d099fad..e581f9127648 100644
--- a/libstdc++-v3/include/bits/random.tcc
+++ b/libstdc++-v3/include/bits/random.tcc
@@ -3173,15 +3173,19 @@ namespace __detail
       __os.fill(__space);
       __os.precision(std::numeric_limits<_RealType>::max_digits10);
 
-      std::vector<_RealType> __int = __x.intervals();
-      __os << __int.size() - 1;
-
-      for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit)
-       __os << __space << *__xit;
-
-      std::vector<double> __den = __x.densities();
-      for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit)
-       __os << __space << *__dit;
+      const auto& __int = __x._M_param._M_int;
+      if (__int.empty())
+       __os << size_t(1)
+            << __space << _RealType(0) << __space << _RealType(1)
+            << __space << _RealType(1);
+      else
+       {
+         __os << __int.size() - 1;
+         for (auto __xv : __int)
+           __os << __space << __xv;
+         for (auto __dv : __x._M_param._M_den)
+           __os << __space << __dv;
+       }
 
       __os.flags(__flags);
       __os.fill(__fill);
@@ -3436,15 +3440,19 @@ namespace __detail
       __os.fill(__space);
       __os.precision(std::numeric_limits<_RealType>::max_digits10);
 
-      std::vector<_RealType> __int = __x.intervals();
-      __os << __int.size() - 1;
-
-      for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit)
-       __os << __space << *__xit;
-
-      std::vector<double> __den = __x.densities();
-      for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit)
-       __os << __space << *__dit;
+      auto const& __int = __x._M_param._M_int;
+      if (__int.empty())
+       __os << size_t(1)
+            << __space << _RealType(0) << __space << _RealType(1)
+            << __space << _RealType(1) << __space << _RealType(1);
+      else
+       {
+         __os << __int.size() - 1;
+         for (auto __xv : __int)
+           __os << __space << __xv;
+         for (auto __dv : __x._M_param._M_den)
+           __os << __space << __dv;
+       }
 
       __os.flags(__flags);
       __os.fill(__fill);

Reply via email to