Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:13:39

0001 //===----------------------------------------------------------------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef _LIBCPP___CXX03___RANDOM_UNIFORM_INT_DISTRIBUTION_H
0010 #define _LIBCPP___CXX03___RANDOM_UNIFORM_INT_DISTRIBUTION_H
0011 
0012 #include <__cxx03/__bit/countl.h>
0013 #include <__cxx03/__config>
0014 #include <__cxx03/__random/is_valid.h>
0015 #include <__cxx03/__random/log2.h>
0016 #include <__cxx03/__type_traits/conditional.h>
0017 #include <__cxx03/__type_traits/make_unsigned.h>
0018 #include <__cxx03/cstddef>
0019 #include <__cxx03/cstdint>
0020 #include <__cxx03/iosfwd>
0021 #include <__cxx03/limits>
0022 
0023 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0024 #  pragma GCC system_header
0025 #endif
0026 
0027 _LIBCPP_PUSH_MACROS
0028 #include <__cxx03/__undef_macros>
0029 
0030 _LIBCPP_BEGIN_NAMESPACE_STD
0031 
0032 template <class _Engine, class _UIntType>
0033 class __independent_bits_engine {
0034 public:
0035   // types
0036   typedef _UIntType result_type;
0037 
0038 private:
0039   typedef typename _Engine::result_type _Engine_result_type;
0040   typedef __conditional_t<sizeof(_Engine_result_type) <= sizeof(result_type), result_type, _Engine_result_type>
0041       _Working_result_type;
0042 
0043   _Engine& __e_;
0044   size_t __w_;
0045   size_t __w0_;
0046   size_t __n_;
0047   size_t __n0_;
0048   _Working_result_type __y0_;
0049   _Working_result_type __y1_;
0050   _Engine_result_type __mask0_;
0051   _Engine_result_type __mask1_;
0052 
0053 #ifdef _LIBCPP_CXX03_LANG
0054   static const _Working_result_type _Rp = _Engine::_Max - _Engine::_Min + _Working_result_type(1);
0055 #else
0056   static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min() + _Working_result_type(1);
0057 #endif
0058   static _LIBCPP_CONSTEXPR const size_t __m  = __log2<_Working_result_type, _Rp>::value;
0059   static _LIBCPP_CONSTEXPR const size_t _WDt = numeric_limits<_Working_result_type>::digits;
0060   static _LIBCPP_CONSTEXPR const size_t _EDt = numeric_limits<_Engine_result_type>::digits;
0061 
0062 public:
0063   // constructors and seeding functions
0064   _LIBCPP_HIDE_FROM_ABI __independent_bits_engine(_Engine& __e, size_t __w);
0065 
0066   // generating functions
0067   _LIBCPP_HIDE_FROM_ABI result_type operator()() { return __eval(integral_constant<bool, _Rp != 0>()); }
0068 
0069 private:
0070   _LIBCPP_HIDE_FROM_ABI result_type __eval(false_type);
0071   _LIBCPP_HIDE_FROM_ABI result_type __eval(true_type);
0072 };
0073 
0074 template <class _Engine, class _UIntType>
0075 __independent_bits_engine<_Engine, _UIntType>::__independent_bits_engine(_Engine& __e, size_t __w)
0076     : __e_(__e), __w_(__w) {
0077   __n_  = __w_ / __m + (__w_ % __m != 0);
0078   __w0_ = __w_ / __n_;
0079   if (_Rp == 0)
0080     __y0_ = _Rp;
0081   else if (__w0_ < _WDt)
0082     __y0_ = (_Rp >> __w0_) << __w0_;
0083   else
0084     __y0_ = 0;
0085   if (_Rp - __y0_ > __y0_ / __n_) {
0086     ++__n_;
0087     __w0_ = __w_ / __n_;
0088     if (__w0_ < _WDt)
0089       __y0_ = (_Rp >> __w0_) << __w0_;
0090     else
0091       __y0_ = 0;
0092   }
0093   __n0_ = __n_ - __w_ % __n_;
0094   if (__w0_ < _WDt - 1)
0095     __y1_ = (_Rp >> (__w0_ + 1)) << (__w0_ + 1);
0096   else
0097     __y1_ = 0;
0098   __mask0_ = __w0_ > 0 ? _Engine_result_type(~0) >> (_EDt - __w0_) : _Engine_result_type(0);
0099   __mask1_ = __w0_ < _EDt - 1 ? _Engine_result_type(~0) >> (_EDt - (__w0_ + 1)) : _Engine_result_type(~0);
0100 }
0101 
0102 template <class _Engine, class _UIntType>
0103 inline _UIntType __independent_bits_engine<_Engine, _UIntType>::__eval(false_type) {
0104   return static_cast<result_type>(__e_() & __mask0_);
0105 }
0106 
0107 template <class _Engine, class _UIntType>
0108 _UIntType __independent_bits_engine<_Engine, _UIntType>::__eval(true_type) {
0109   const size_t __w_rt = numeric_limits<result_type>::digits;
0110   result_type __sp    = 0;
0111   for (size_t __k = 0; __k < __n0_; ++__k) {
0112     _Engine_result_type __u;
0113     do {
0114       __u = __e_() - _Engine::min();
0115     } while (__u >= __y0_);
0116     if (__w0_ < __w_rt)
0117       __sp <<= __w0_;
0118     else
0119       __sp = 0;
0120     __sp += __u & __mask0_;
0121   }
0122   for (size_t __k = __n0_; __k < __n_; ++__k) {
0123     _Engine_result_type __u;
0124     do {
0125       __u = __e_() - _Engine::min();
0126     } while (__u >= __y1_);
0127     if (__w0_ < __w_rt - 1)
0128       __sp <<= __w0_ + 1;
0129     else
0130       __sp = 0;
0131     __sp += __u & __mask1_;
0132   }
0133   return __sp;
0134 }
0135 
0136 template <class _IntType = int>
0137 class uniform_int_distribution {
0138   static_assert(__libcpp_random_is_valid_inttype<_IntType>::value, "IntType must be a supported integer type");
0139 
0140 public:
0141   // types
0142   typedef _IntType result_type;
0143 
0144   class param_type {
0145     result_type __a_;
0146     result_type __b_;
0147 
0148   public:
0149     typedef uniform_int_distribution distribution_type;
0150 
0151     _LIBCPP_HIDE_FROM_ABI explicit param_type(result_type __a = 0, result_type __b = numeric_limits<result_type>::max())
0152         : __a_(__a), __b_(__b) {}
0153 
0154     _LIBCPP_HIDE_FROM_ABI result_type a() const { return __a_; }
0155     _LIBCPP_HIDE_FROM_ABI result_type b() const { return __b_; }
0156 
0157     _LIBCPP_HIDE_FROM_ABI friend bool operator==(const param_type& __x, const param_type& __y) {
0158       return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;
0159     }
0160     _LIBCPP_HIDE_FROM_ABI friend bool operator!=(const param_type& __x, const param_type& __y) { return !(__x == __y); }
0161   };
0162 
0163 private:
0164   param_type __p_;
0165 
0166 public:
0167   // constructors and reset functions
0168 #ifndef _LIBCPP_CXX03_LANG
0169   _LIBCPP_HIDE_FROM_ABI uniform_int_distribution() : uniform_int_distribution(0) {}
0170   _LIBCPP_HIDE_FROM_ABI explicit uniform_int_distribution(
0171       result_type __a, result_type __b = numeric_limits<result_type>::max())
0172       : __p_(param_type(__a, __b)) {}
0173 #else
0174   explicit uniform_int_distribution(result_type __a = 0, result_type __b = numeric_limits<result_type>::max())
0175       : __p_(param_type(__a, __b)) {}
0176 #endif
0177   _LIBCPP_HIDE_FROM_ABI explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {}
0178   _LIBCPP_HIDE_FROM_ABI void reset() {}
0179 
0180   // generating functions
0181   template <class _URNG>
0182   _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g) {
0183     return (*this)(__g, __p_);
0184   }
0185   template <class _URNG>
0186   _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p);
0187 
0188   // property functions
0189   _LIBCPP_HIDE_FROM_ABI result_type a() const { return __p_.a(); }
0190   _LIBCPP_HIDE_FROM_ABI result_type b() const { return __p_.b(); }
0191 
0192   _LIBCPP_HIDE_FROM_ABI param_type param() const { return __p_; }
0193   _LIBCPP_HIDE_FROM_ABI void param(const param_type& __p) { __p_ = __p; }
0194 
0195   _LIBCPP_HIDE_FROM_ABI result_type min() const { return a(); }
0196   _LIBCPP_HIDE_FROM_ABI result_type max() const { return b(); }
0197 
0198   _LIBCPP_HIDE_FROM_ABI friend bool
0199   operator==(const uniform_int_distribution& __x, const uniform_int_distribution& __y) {
0200     return __x.__p_ == __y.__p_;
0201   }
0202   _LIBCPP_HIDE_FROM_ABI friend bool
0203   operator!=(const uniform_int_distribution& __x, const uniform_int_distribution& __y) {
0204     return !(__x == __y);
0205   }
0206 };
0207 
0208 template <class _IntType>
0209 template <class _URNG>
0210 typename uniform_int_distribution<_IntType>::result_type uniform_int_distribution<_IntType>::operator()(
0211     _URNG& __g, const param_type& __p) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK {
0212   static_assert(__libcpp_random_is_valid_urng<_URNG>::value, "");
0213   typedef __conditional_t<sizeof(result_type) <= sizeof(uint32_t), uint32_t, __make_unsigned_t<result_type> > _UIntType;
0214   const _UIntType __rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1);
0215   if (__rp == 1)
0216     return __p.a();
0217   const size_t __dt = numeric_limits<_UIntType>::digits;
0218   typedef __independent_bits_engine<_URNG, _UIntType> _Eng;
0219   if (__rp == 0)
0220     return static_cast<result_type>(_Eng(__g, __dt)());
0221   size_t __w = __dt - std::__countl_zero(__rp) - 1;
0222   if ((__rp & (numeric_limits<_UIntType>::max() >> (__dt - __w))) != 0)
0223     ++__w;
0224   _Eng __e(__g, __w);
0225   _UIntType __u;
0226   do {
0227     __u = __e();
0228   } while (__u >= __rp);
0229   return static_cast<result_type>(__u + __p.a());
0230 }
0231 
0232 template <class _CharT, class _Traits, class _IT>
0233 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0234 operator<<(basic_ostream<_CharT, _Traits>& __os, const uniform_int_distribution<_IT>& __x) {
0235   __save_flags<_CharT, _Traits> __lx(__os);
0236   typedef basic_ostream<_CharT, _Traits> _Ostream;
0237   __os.flags(_Ostream::dec | _Ostream::left);
0238   _CharT __sp = __os.widen(' ');
0239   __os.fill(__sp);
0240   return __os << __x.a() << __sp << __x.b();
0241 }
0242 
0243 template <class _CharT, class _Traits, class _IT>
0244 _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
0245 operator>>(basic_istream<_CharT, _Traits>& __is, uniform_int_distribution<_IT>& __x) {
0246   typedef uniform_int_distribution<_IT> _Eng;
0247   typedef typename _Eng::result_type result_type;
0248   typedef typename _Eng::param_type param_type;
0249   __save_flags<_CharT, _Traits> __lx(__is);
0250   typedef basic_istream<_CharT, _Traits> _Istream;
0251   __is.flags(_Istream::dec | _Istream::skipws);
0252   result_type __a;
0253   result_type __b;
0254   __is >> __a >> __b;
0255   if (!__is.fail())
0256     __x.param(param_type(__a, __b));
0257   return __is;
0258 }
0259 
0260 _LIBCPP_END_NAMESPACE_STD
0261 
0262 _LIBCPP_POP_MACROS
0263 
0264 #endif // _LIBCPP___CXX03___RANDOM_UNIFORM_INT_DISTRIBUTION_H