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 
__p_(__p)37*cb14a3feSDimitry Andric     _LIBCPP_HIDE_FROM_ABI explicit param_type(double __p = 0.5) : __p_(__p) {}
384824e7fdSDimitry Andric 
p()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
bernoulli_distribution()53*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI bernoulli_distribution() : bernoulli_distribution(0.5) {}
bernoulli_distribution(double __p)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
bernoulli_distribution(const param_type & __p)58*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit bernoulli_distribution(const param_type& __p) : __p_(__p) {}
reset()59*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void reset() {}
604824e7fdSDimitry Andric 
614824e7fdSDimitry Andric   // generating functions
624824e7fdSDimitry Andric   template <class _URNG>
operator()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
p()70*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI double p() const { return __p_.p(); }
714824e7fdSDimitry Andric 
param()72*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI param_type param() const { return __p_; }
param(const param_type & __p)73*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI void param(const param_type& __p) { __p_ = __p; }
744824e7fdSDimitry Andric 
min()75*cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI result_type min() const { return false; }
max()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>
operator()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