14824e7fdSDimitry Andric //===----------------------------------------------------------------------===// 24824e7fdSDimitry Andric // 34824e7fdSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 44824e7fdSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 54824e7fdSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 64824e7fdSDimitry Andric // 74824e7fdSDimitry Andric //===----------------------------------------------------------------------===// 84824e7fdSDimitry Andric 94824e7fdSDimitry Andric #ifndef _LIBCPP___RANDOM_BERNOULLI_DISTRIBUTION_H 104824e7fdSDimitry Andric #define _LIBCPP___RANDOM_BERNOULLI_DISTRIBUTION_H 114824e7fdSDimitry Andric 124824e7fdSDimitry Andric #include <__config> 1381ad6265SDimitry Andric #include <__random/is_valid.h> 144824e7fdSDimitry Andric #include <__random/uniform_real_distribution.h> 154824e7fdSDimitry Andric #include <iosfwd> 164824e7fdSDimitry Andric 174824e7fdSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 184824e7fdSDimitry Andric # pragma GCC system_header 194824e7fdSDimitry Andric #endif 204824e7fdSDimitry Andric 214824e7fdSDimitry Andric _LIBCPP_PUSH_MACROS 224824e7fdSDimitry Andric #include <__undef_macros> 234824e7fdSDimitry Andric 244824e7fdSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 254824e7fdSDimitry Andric 26*cb14a3feSDimitry Andric class _LIBCPP_TEMPLATE_VIS bernoulli_distribution { 274824e7fdSDimitry Andric public: 284824e7fdSDimitry Andric // types 294824e7fdSDimitry Andric typedef bool result_type; 304824e7fdSDimitry Andric 31*cb14a3feSDimitry Andric class _LIBCPP_TEMPLATE_VIS param_type { 324824e7fdSDimitry Andric double __p_; 33*cb14a3feSDimitry Andric 344824e7fdSDimitry Andric public: 354824e7fdSDimitry Andric typedef bernoulli_distribution distribution_type; 364824e7fdSDimitry Andric 37*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit param_type(double __p = 0.5) : __p_(__p) {} 384824e7fdSDimitry Andric 39*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI double p() const { return __p_; } 404824e7fdSDimitry Andric 41*cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator==(const param_type& __x, const param_type& __y) { 42*cb14a3feSDimitry Andric return __x.__p_ == __y.__p_; 43*cb14a3feSDimitry Andric } 44*cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const param_type& __x, const param_type& __y) { return !(__x == __y); } 454824e7fdSDimitry Andric }; 464824e7fdSDimitry Andric 474824e7fdSDimitry Andric private: 484824e7fdSDimitry Andric param_type __p_; 494824e7fdSDimitry Andric 504824e7fdSDimitry Andric public: 514824e7fdSDimitry Andric // constructors and reset functions 524824e7fdSDimitry Andric #ifndef _LIBCPP_CXX03_LANG 53*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bernoulli_distribution() : bernoulli_distribution(0.5) {} 54*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit bernoulli_distribution(double __p) : __p_(param_type(__p)) {} 554824e7fdSDimitry Andric #else 56*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit bernoulli_distribution(double __p = 0.5) : __p_(param_type(__p)) {} 574824e7fdSDimitry Andric #endif 58*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit bernoulli_distribution(const param_type& __p) : __p_(__p) {} 59*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void reset() {} 604824e7fdSDimitry Andric 614824e7fdSDimitry Andric // generating functions 624824e7fdSDimitry Andric template <class _URNG> 63*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g) { 64*cb14a3feSDimitry Andric return (*this)(__g, __p_); 65*cb14a3feSDimitry Andric } 66*cb14a3feSDimitry Andric template <class _URNG> 67*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); 684824e7fdSDimitry Andric 694824e7fdSDimitry Andric // property functions 70*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI double p() const { return __p_.p(); } 714824e7fdSDimitry Andric 72*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI param_type param() const { return __p_; } 73*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void param(const param_type& __p) { __p_ = __p; } 744824e7fdSDimitry Andric 75*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI result_type min() const { return false; } 76*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI result_type max() const { return true; } 774824e7fdSDimitry Andric 78*cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator==(const bernoulli_distribution& __x, const bernoulli_distribution& __y) { 79*cb14a3feSDimitry Andric return __x.__p_ == __y.__p_; 80*cb14a3feSDimitry Andric } 81*cb14a3feSDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const bernoulli_distribution& __x, const bernoulli_distribution& __y) { 82*cb14a3feSDimitry Andric return !(__x == __y); 83*cb14a3feSDimitry Andric } 844824e7fdSDimitry Andric }; 854824e7fdSDimitry Andric 864824e7fdSDimitry Andric template <class _URNG> 87*cb14a3feSDimitry Andric inline bernoulli_distribution::result_type bernoulli_distribution::operator()(_URNG& __g, const param_type& __p) { 8881ad6265SDimitry Andric static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); 894824e7fdSDimitry Andric uniform_real_distribution<double> __gen; 904824e7fdSDimitry Andric return __gen(__g) < __p.p(); 914824e7fdSDimitry Andric } 924824e7fdSDimitry Andric 934824e7fdSDimitry Andric template <class _CharT, class _Traits> 94bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 95*cb14a3feSDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, const bernoulli_distribution& __x) { 964824e7fdSDimitry Andric __save_flags<_CharT, _Traits> __lx(__os); 974824e7fdSDimitry Andric typedef basic_ostream<_CharT, _Traits> _OStream; 98*cb14a3feSDimitry Andric __os.flags(_OStream::dec | _OStream::left | _OStream::fixed | _OStream::scientific); 994824e7fdSDimitry Andric _CharT __sp = __os.widen(' '); 1004824e7fdSDimitry Andric __os.fill(__sp); 1014824e7fdSDimitry Andric return __os << __x.p(); 1024824e7fdSDimitry Andric } 1034824e7fdSDimitry Andric 1044824e7fdSDimitry Andric template <class _CharT, class _Traits> 105bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 106*cb14a3feSDimitry Andric operator>>(basic_istream<_CharT, _Traits>& __is, bernoulli_distribution& __x) { 1074824e7fdSDimitry Andric typedef bernoulli_distribution _Eng; 1084824e7fdSDimitry Andric typedef typename _Eng::param_type param_type; 1094824e7fdSDimitry Andric __save_flags<_CharT, _Traits> __lx(__is); 1104824e7fdSDimitry Andric typedef basic_istream<_CharT, _Traits> _Istream; 1114824e7fdSDimitry Andric __is.flags(_Istream::dec | _Istream::skipws); 1124824e7fdSDimitry Andric double __p; 1134824e7fdSDimitry Andric __is >> __p; 1144824e7fdSDimitry Andric if (!__is.fail()) 1154824e7fdSDimitry Andric __x.param(param_type(__p)); 1164824e7fdSDimitry Andric return __is; 1174824e7fdSDimitry Andric } 1184824e7fdSDimitry Andric 1194824e7fdSDimitry Andric _LIBCPP_END_NAMESPACE_STD 1204824e7fdSDimitry Andric 1214824e7fdSDimitry Andric _LIBCPP_POP_MACROS 1224824e7fdSDimitry Andric 1234824e7fdSDimitry Andric #endif // _LIBCPP___RANDOM_BERNOULLI_DISTRIBUTION_H 124