1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef _LIBCPP___RANDOM_GEOMETRIC_DISTRIBUTION_H
10 #define _LIBCPP___RANDOM_GEOMETRIC_DISTRIBUTION_H
11 
12 #include <__config>
13 #include <__random/is_valid.h>
14 #include <__random/negative_binomial_distribution.h>
15 #include <iosfwd>
16 #include <limits>
17 
18 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19 #  pragma GCC system_header
20 #endif
21 
22 _LIBCPP_PUSH_MACROS
23 #include <__undef_macros>
24 
25 _LIBCPP_BEGIN_NAMESPACE_STD
26 
27 template<class _IntType = int>
28 class _LIBCPP_TEMPLATE_VIS geometric_distribution
29 {
30     static_assert(__libcpp_random_is_valid_inttype<_IntType>::value, "IntType must be a supported integer type");
31 public:
32     // types
33     typedef _IntType result_type;
34 
35     class _LIBCPP_TEMPLATE_VIS param_type
36     {
37         double __p_;
38     public:
39         typedef geometric_distribution distribution_type;
40 
41         _LIBCPP_INLINE_VISIBILITY
42         explicit param_type(double __p = 0.5) : __p_(__p) {}
43 
44         _LIBCPP_INLINE_VISIBILITY
45         double p() const {return __p_;}
46 
47         friend _LIBCPP_INLINE_VISIBILITY
48             bool operator==(const param_type& __x, const param_type& __y)
49             {return __x.__p_ == __y.__p_;}
50         friend _LIBCPP_INLINE_VISIBILITY
51             bool operator!=(const param_type& __x, const param_type& __y)
52             {return !(__x == __y);}
53     };
54 
55 private:
56     param_type __p_;
57 
58 public:
59     // constructors and reset functions
60 #ifndef _LIBCPP_CXX03_LANG
61     _LIBCPP_INLINE_VISIBILITY
62     geometric_distribution() : geometric_distribution(0.5) {}
63     _LIBCPP_INLINE_VISIBILITY
64     explicit geometric_distribution(double __p)
65         : __p_(__p) {}
66 #else
67     _LIBCPP_INLINE_VISIBILITY
68     explicit geometric_distribution(double __p = 0.5)
69         : __p_(__p) {}
70 #endif
71     _LIBCPP_INLINE_VISIBILITY
72     explicit geometric_distribution(const param_type& __p) : __p_(__p) {}
73     _LIBCPP_INLINE_VISIBILITY
74     void reset() {}
75 
76     // generating functions
77     template<class _URNG>
78         _LIBCPP_INLINE_VISIBILITY
79         result_type operator()(_URNG& __g)
80         {return (*this)(__g, __p_);}
81     template<class _URNG>
82         _LIBCPP_INLINE_VISIBILITY
83         result_type operator()(_URNG& __g, const param_type& __p)
84         {return negative_binomial_distribution<result_type>(1, __p.p())(__g);}
85 
86     // property functions
87     _LIBCPP_INLINE_VISIBILITY
88     double p() const {return __p_.p();}
89 
90     _LIBCPP_INLINE_VISIBILITY
91     param_type param() const {return __p_;}
92     _LIBCPP_INLINE_VISIBILITY
93     void param(const param_type& __p) {__p_ = __p;}
94 
95     _LIBCPP_INLINE_VISIBILITY
96     result_type min() const {return 0;}
97     _LIBCPP_INLINE_VISIBILITY
98     result_type max() const {return numeric_limits<result_type>::max();}
99 
100     friend _LIBCPP_INLINE_VISIBILITY
101         bool operator==(const geometric_distribution& __x,
102                         const geometric_distribution& __y)
103         {return __x.__p_ == __y.__p_;}
104     friend _LIBCPP_INLINE_VISIBILITY
105         bool operator!=(const geometric_distribution& __x,
106                         const geometric_distribution& __y)
107         {return !(__x == __y);}
108 };
109 
110 template <class _CharT, class _Traits, class _IntType>
111 basic_ostream<_CharT, _Traits>&
112 operator<<(basic_ostream<_CharT, _Traits>& __os,
113            const geometric_distribution<_IntType>& __x)
114 {
115     __save_flags<_CharT, _Traits> __lx(__os);
116     typedef basic_ostream<_CharT, _Traits> _OStream;
117     __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
118                _OStream::scientific);
119     return __os << __x.p();
120 }
121 
122 template <class _CharT, class _Traits, class _IntType>
123 basic_istream<_CharT, _Traits>&
124 operator>>(basic_istream<_CharT, _Traits>& __is,
125            geometric_distribution<_IntType>& __x)
126 {
127     typedef geometric_distribution<_IntType> _Eng;
128     typedef typename _Eng::param_type param_type;
129     __save_flags<_CharT, _Traits> __lx(__is);
130     typedef basic_istream<_CharT, _Traits> _Istream;
131     __is.flags(_Istream::dec | _Istream::skipws);
132     double __p;
133     __is >> __p;
134     if (!__is.fail())
135         __x.param(param_type(__p));
136     return __is;
137 }
138 
139 _LIBCPP_END_NAMESPACE_STD
140 
141 _LIBCPP_POP_MACROS
142 
143 #endif // _LIBCPP___RANDOM_GEOMETRIC_DISTRIBUTION_H
144