diff options
Diffstat (limited to 'libstdc++-v3/include/ext/random.tcc')
-rw-r--r-- | libstdc++-v3/include/ext/random.tcc | 108 |
1 files changed, 107 insertions, 1 deletions
diff --git a/libstdc++-v3/include/ext/random.tcc b/libstdc++-v3/include/ext/random.tcc index 009e0effba8..7d68958c093 100644 --- a/libstdc++-v3/include/ext/random.tcc +++ b/libstdc++-v3/include/ext/random.tcc @@ -32,7 +32,6 @@ #pragma GCC system_header - namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -1307,6 +1306,113 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __is; } + + template<typename _UIntType> + template<typename _UniformRandomNumberGenerator> + typename hypergeometric_distribution<_UIntType>::result_type + hypergeometric_distribution<_UIntType>:: + operator()(_UniformRandomNumberGenerator& __urng, + const param_type& __param) + { + std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> + __aurng(__urng); + + result_type __a = __param.successful_size(); + result_type __b = __param.total_size(); + result_type __k = 0; + + if (__param.total_draws() < __param.total_size() / 2) + { + for (result_type __i = 0; __i < __param.total_draws(); ++__i) + { + if (__b * __aurng() < __a) + { + ++__k; + if (__k == __param.successful_size()) + return __k; + --__a; + } + --__b; + } + return __k; + } + else + { + for (result_type __i = 0; __i < __param.unsuccessful_size(); ++__i) + { + if (__b * __aurng() < __a) + { + ++__k; + if (__k == __param.successful_size()) + return __param.successful_size() - __k; + --__a; + } + --__b; + } + return __param.successful_size() - __k; + } + } + + template<typename _UIntType> + template<typename _OutputIterator, + typename _UniformRandomNumberGenerator> + void + hypergeometric_distribution<_UIntType>:: + __generate_impl(_OutputIterator __f, _OutputIterator __t, + _UniformRandomNumberGenerator& __urng, + const param_type& __param) + { + __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator>) + + while (__f != __t) + *__f++ = this->operator()(__urng); + } + + template<typename _UIntType, typename _CharT, typename _Traits> + std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const __gnu_cxx::hypergeometric_distribution<_UIntType>& __x) + { + typedef std::basic_ostream<_CharT, _Traits> __ostream_type; + typedef typename __ostream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __os.flags(); + const _CharT __fill = __os.fill(); + const std::streamsize __precision = __os.precision(); + const _CharT __space = __os.widen(' '); + __os.flags(__ios_base::scientific | __ios_base::left); + __os.fill(__space); + __os.precision(std::numeric_limits<_UIntType>::max_digits10); + + __os << __x.total_size() << __space << __x.successful_size() << __space + << __x.total_draws(); + + __os.flags(__flags); + __os.fill(__fill); + __os.precision(__precision); + return __os; + } + + template<typename _UIntType, typename _CharT, typename _Traits> + std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + __gnu_cxx::hypergeometric_distribution<_UIntType>& __x) + { + typedef std::basic_istream<_CharT, _Traits> __istream_type; + typedef typename __istream_type::ios_base __ios_base; + + const typename __ios_base::fmtflags __flags = __is.flags(); + __is.flags(__ios_base::dec | __ios_base::skipws); + + _UIntType __total_size, __successful_size, __total_draws; + __is >> __total_size >> __successful_size >> __total_draws; + __x.param(typename __gnu_cxx::hypergeometric_distribution<_UIntType>:: + param_type(__total_size, __successful_size, __total_draws)); + + __is.flags(__flags); + return __is; + } + _GLIBCXX_END_NAMESPACE_VERSION } // namespace |