[libcxx-commits] [libcxx] 0359b85 - [libc++] [ABI BREAK] Conform lognormal_distribution::param_type.

Arthur O'Dwyer via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jan 17 07:24:51 PST 2022


Author: Arthur O'Dwyer
Date: 2022-01-17T10:22:41-05:00
New Revision: 0359b85c61b54354949a68f41a6881fb15f1c22b

URL: https://github.com/llvm/llvm-project/commit/0359b85c61b54354949a68f41a6881fb15f1c22b
DIFF: https://github.com/llvm/llvm-project/commit/0359b85c61b54354949a68f41a6881fb15f1c22b.diff

LOG: [libc++] [ABI BREAK] Conform lognormal_distribution::param_type.

Fixes #52906.

Differential Revision: https://reviews.llvm.org/D116344

Added: 
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/eval_param.PR52906.pass.cpp

Modified: 
    libcxx/docs/ReleaseNotes.rst
    libcxx/include/__random/lognormal_distribution.h

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst
index 1a8c0071cec23..4a1831268f807 100644
--- a/libcxx/docs/ReleaseNotes.rst
+++ b/libcxx/docs/ReleaseNotes.rst
@@ -119,6 +119,15 @@ ABI Changes
   constructing a ``std::random_device`` will now be ignored instead of interpreted as a
   file to read entropy from.
 
+- ``std::lognormal_distribution::param_type`` used to store a data member of type
+  ``std::normal_distribution``; now this member is stored in the ``lognormal_distribution``
+  class itself, and the ``param_type`` stores only the mean and standard deviation,
+  as required by the Standard. This changes ``sizeof(std::lognormal_distribution::param_type)``.
+  You can define the ``_LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION`` macro to return to the
+  previous behavior. That macro will be removed in LLVM 15. Please comment
+  `here <https://llvm.org/PR52906>`_ if you are broken by this change and need to
+  define the macro.
+
 Build System Changes
 --------------------
 

diff  --git a/libcxx/include/__random/lognormal_distribution.h b/libcxx/include/__random/lognormal_distribution.h
index 752861c3de0cf..8fadb5a1e66a4 100644
--- a/libcxx/include/__random/lognormal_distribution.h
+++ b/libcxx/include/__random/lognormal_distribution.h
@@ -24,6 +24,8 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+#ifdef _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION
+
 template<class _RealType = double>
 class _LIBCPP_TEMPLATE_VIS lognormal_distribution
 {
@@ -156,6 +158,140 @@ operator>>(basic_istream<_CharT, _Traits>& __is,
     return __is >> __x.__p_.__nd_;
 }
 
+#else // _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION
+
+template<class _RealType = double>
+class _LIBCPP_TEMPLATE_VIS lognormal_distribution
+{
+public:
+    // types
+    typedef _RealType result_type;
+
+    class _LIBCPP_TEMPLATE_VIS param_type
+    {
+        result_type __m_;
+        result_type __s_;
+    public:
+        typedef lognormal_distribution distribution_type;
+
+        _LIBCPP_INLINE_VISIBILITY
+        explicit param_type(result_type __m = 0, result_type __s = 1)
+            : __m_(__m), __s_(__s) {}
+
+        _LIBCPP_INLINE_VISIBILITY
+        result_type m() const {return __m_;}
+        _LIBCPP_INLINE_VISIBILITY
+        result_type s() const {return __s_;}
+
+        friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const param_type& __x, const param_type& __y)
+            {return __x.__m_ == __y.__m_ && __x.__s_ == __y.__s_;}
+        friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const param_type& __x, const param_type& __y)
+            {return !(__x == __y);}
+    };
+
+private:
+    normal_distribution<result_type> __nd_;
+
+public:
+    // constructor and reset functions
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    lognormal_distribution() : lognormal_distribution(0) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit lognormal_distribution(result_type __m, result_type __s = 1)
+        : __nd_(__m, __s) {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    explicit lognormal_distribution(result_type __m = 0,
+                                    result_type __s = 1)
+        : __nd_(__m, __s) {}
+#endif
+    _LIBCPP_INLINE_VISIBILITY
+    explicit lognormal_distribution(const param_type& __p)
+        : __nd_(__p.m(), __p.s()) {}
+    _LIBCPP_INLINE_VISIBILITY
+    void reset() {__nd_.reset();}
+
+    // generating functions
+    template<class _URNG>
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator()(_URNG& __g)
+    {
+        return _VSTD::exp(__nd_(__g));
+    }
+
+    template<class _URNG>
+    _LIBCPP_INLINE_VISIBILITY
+    result_type operator()(_URNG& __g, const param_type& __p)
+    {
+        typename normal_distribution<result_type>::param_type __pn(__p.m(), __p.s());
+        return _VSTD::exp(__nd_(__g, __pn));
+    }
+
+    // property functions
+    _LIBCPP_INLINE_VISIBILITY
+    result_type m() const {return __nd_.mean();}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type s() const {return __nd_.stddev();}
+
+    _LIBCPP_INLINE_VISIBILITY
+    param_type param() const {return param_type(__nd_.mean(), __nd_.stddev());}
+    _LIBCPP_INLINE_VISIBILITY
+    void param(const param_type& __p)
+    {
+        typename normal_distribution<result_type>::param_type __pn(__p.m(), __p.s());
+        __nd_.param(__pn);
+    }
+
+    _LIBCPP_INLINE_VISIBILITY
+    result_type min() const {return 0;}
+    _LIBCPP_INLINE_VISIBILITY
+    result_type max() const {return numeric_limits<result_type>::infinity();}
+
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator==(const lognormal_distribution& __x,
+                        const lognormal_distribution& __y)
+        {return __x.__nd_ == __y.__nd_;}
+    friend _LIBCPP_INLINE_VISIBILITY
+        bool operator!=(const lognormal_distribution& __x,
+                        const lognormal_distribution& __y)
+        {return !(__x == __y);}
+
+    template <class _CharT, class _Traits, class _RT>
+    friend
+    basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os,
+               const lognormal_distribution<_RT>& __x);
+
+    template <class _CharT, class _Traits, class _RT>
+    friend
+    basic_istream<_CharT, _Traits>&
+    operator>>(basic_istream<_CharT, _Traits>& __is,
+               lognormal_distribution<_RT>& __x);
+};
+
+template <class _CharT, class _Traits, class _RT>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os,
+           const lognormal_distribution<_RT>& __x)
+{
+    return __os << __x.__nd_;
+}
+
+template <class _CharT, class _Traits, class _RT>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_istream<_CharT, _Traits>&
+operator>>(basic_istream<_CharT, _Traits>& __is,
+           lognormal_distribution<_RT>& __x)
+{
+    return __is >> __x.__nd_;
+}
+
+#endif // _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION
+
 _LIBCPP_END_NAMESPACE_STD
 
 _LIBCPP_POP_MACROS

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/eval_param.PR52906.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/eval_param.PR52906.pass.cpp
new file mode 100644
index 0000000000000..d360b11fdc587
--- /dev/null
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/eval_param.PR52906.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <random>
+
+// template<class RealType = double>
+// class lognormal_distribution
+
+// template<class _URNG> result_type operator()(_URNG& g, const param_type& parm);
+//   https://llvm.org/PR52906
+
+#include <random>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**)
+{
+    typedef std::lognormal_distribution<> D;
+    typedef D::param_type P;
+    typedef std::mt19937 G;
+    G g;
+    D d;
+
+    const P p1 = d.param();
+    const P p2 = d.param();
+    assert(p1 == p2);
+    (void) d(g, p1); // This line must not modify p1.
+    assert(p1 == p2);
+    LIBCPP_ASSERT(p1 == d.param());
+
+    return 0;
+}


        


More information about the libcxx-commits mailing list