File indexing completed on 2026-05-03 08:14:01
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H
0010 #define _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H
0011
0012 #include <__bit/countl.h>
0013 #include <__config>
0014 #include <__cstddef/size_t.h>
0015 #include <__random/is_valid.h>
0016 #include <__random/log2.h>
0017 #include <__type_traits/conditional.h>
0018 #include <__type_traits/make_unsigned.h>
0019 #include <cstdint>
0020 #include <iosfwd>
0021 #include <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 <__undef_macros>
0029
0030 _LIBCPP_BEGIN_NAMESPACE_STD
0031
0032 template <class _Engine, class _UIntType>
0033 class __independent_bits_engine {
0034 public:
0035
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
0064 _LIBCPP_HIDE_FROM_ABI __independent_bits_engine(_Engine& __e, size_t __w);
0065
0066
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
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
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
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
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