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