@@ -5953,73 +5953,6 @@ namespace ranges {
59535953#endif // _HAS_CXX20
59545954#endif // _HAS_CXX17
59555955
5956- template <class _Diff, class _Urng>
5957- class _Rng_from_urng { // wrap a URNG as an RNG
5958- public:
5959- using _Ty0 = make_unsigned_t<_Diff>;
5960- using _Ty1 = _Invoke_result_t<_Urng&>;
5961-
5962- using _Udiff = conditional_t<sizeof(_Ty1) < sizeof(_Ty0), _Ty0, _Ty1>;
5963-
5964- explicit _Rng_from_urng(_Urng& _Func)
5965- : _Ref(_Func), _Bits(CHAR_BIT * sizeof(_Udiff)), _Bmask(static_cast<_Udiff>(-1)) {
5966- for (; static_cast<_Udiff>((_Urng::max) () - (_Urng::min) ()) < _Bmask; _Bmask >>= 1) {
5967- --_Bits;
5968- }
5969- }
5970-
5971- _Diff operator()(_Diff _Index) { // adapt _Urng closed range to [0, _Index)
5972- for (;;) { // try a sample random value
5973- _Udiff _Ret = 0; // random bits
5974- _Udiff _Mask = 0; // 2^N - 1, _Ret is within [0, _Mask]
5975-
5976- while (_Mask < static_cast<_Udiff>(_Index - 1)) { // need more random bits
5977- _Ret <<= _Bits - 1; // avoid full shift
5978- _Ret <<= 1;
5979- _Ret |= _Get_bits();
5980- _Mask <<= _Bits - 1; // avoid full shift
5981- _Mask <<= 1;
5982- _Mask |= _Bmask;
5983- }
5984-
5985- // _Ret is [0, _Mask], _Index - 1 <= _Mask, return if unbiased
5986- if (_Ret / _Index < _Mask / _Index || _Mask % _Index == static_cast<_Udiff>(_Index - 1)) {
5987- return static_cast<_Diff>(_Ret % _Index);
5988- }
5989- }
5990- }
5991-
5992- _Udiff _Get_all_bits() {
5993- _Udiff _Ret = 0;
5994-
5995- for (size_t _Num = 0; _Num < CHAR_BIT * sizeof(_Udiff); _Num += _Bits) { // don't mask away any bits
5996- _Ret <<= _Bits - 1; // avoid full shift
5997- _Ret <<= 1;
5998- _Ret |= _Get_bits();
5999- }
6000-
6001- return _Ret;
6002- }
6003-
6004- _Rng_from_urng(const _Rng_from_urng&) = delete;
6005- _Rng_from_urng& operator=(const _Rng_from_urng&) = delete;
6006-
6007- private:
6008- _Udiff _Get_bits() { // return a random value within [0, _Bmask]
6009- for (;;) { // repeat until random value is in range
6010- const _Udiff _Val = static_cast<_Udiff>(_Ref() - (_Urng::min) ());
6011-
6012- if (_Val <= _Bmask) {
6013- return _Val;
6014- }
6015- }
6016- }
6017-
6018- _Urng& _Ref; // reference to URNG
6019- size_t _Bits; // number of random bits generated by _Get_bits()
6020- _Udiff _Bmask; // 2^_Bits - 1
6021- };
6022-
60235956template <class _Diff, class _Urng>
60245957class _Rng_from_urng_v2 { // wrap a URNG as an RNG
60255958public:
@@ -6142,19 +6075,6 @@ private:
61426075 static constexpr _Udiff _Bmask = static_cast<_Udiff>(-1) >> (_Udiff_bits - _Bits); // 2^_Bits - 1
61436076};
61446077
6145- template <class _Gen, class = void>
6146- constexpr bool _Has_static_min_max = false;
6147-
6148- // This checks a requirement of N4981 [rand.req.urng] `concept uniform_random_bit_generator` but doesn't attempt
6149- // to implement the whole concept - we just need to distinguish Standard machinery from tr1 machinery.
6150- template <class _Gen>
6151- constexpr bool _Has_static_min_max<_Gen, void_t<decltype(bool_constant<(_Gen::min) () < (_Gen::max) ()>::value)>> =
6152- true;
6153-
6154- template <class _Diff, class _Urng>
6155- using _Rng_from_urng_v1_or_v2 =
6156- conditional_t<_Has_static_min_max<_Urng>, _Rng_from_urng_v2<_Diff, _Urng>, _Rng_from_urng<_Diff, _Urng>>;
6157-
61586078#if _HAS_CXX17
61596079template <class _PopIt, class _SampleIt, class _Diff, class _RngFn>
61606080_SampleIt _Sample_reservoir_unchecked(
@@ -6212,7 +6132,7 @@ _SampleIt sample(_PopIt _First, _PopIt _Last, _SampleIt _Dest, _Diff _Count, _Ur
62126132 auto _UFirst = _STD _Get_unwrapped(_First);
62136133 auto _ULast = _STD _Get_unwrapped(_Last);
62146134 using _PopDiff = _Iter_diff_t<_PopIt>;
6215- _Rng_from_urng_v1_or_v2 <_PopDiff, remove_reference_t<_Urng>> _RngFunc(_Func);
6135+ _Rng_from_urng_v2 <_PopDiff, remove_reference_t<_Urng>> _RngFunc(_Func);
62166136 if constexpr (_Is_ranges_fwd_iter_v<_PopIt>) {
62176137 // source is forward: use selection sampling (stable)
62186138 using _CT = common_type_t<_Diff, _PopDiff>;
@@ -6255,7 +6175,7 @@ namespace ranges {
62556175 return _Output;
62566176 }
62576177
6258- _Rng_from_urng_v1_or_v2 <iter_difference_t<_It>, remove_reference_t<_Urng>> _RngFunc(_Func);
6178+ _Rng_from_urng_v2 <iter_difference_t<_It>, remove_reference_t<_Urng>> _RngFunc(_Func);
62596179 if constexpr (forward_iterator<_It>) {
62606180 auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First));
62616181 auto _Pop_size = _RANGES distance(_UFirst, _RANGES _Unwrap_sent<_It>(_STD move(_Last)));
@@ -6276,7 +6196,7 @@ namespace ranges {
62766196 return _Output;
62776197 }
62786198
6279- _Rng_from_urng_v1_or_v2 <range_difference_t<_Rng>, remove_reference_t<_Urng>> _RngFunc(_Func);
6199+ _Rng_from_urng_v2 <range_difference_t<_Rng>, remove_reference_t<_Urng>> _RngFunc(_Func);
62806200 if constexpr (forward_range<_Rng>) {
62816201 auto _UFirst = _Ubegin(_Range);
62826202 auto _Pop_size = _RANGES distance(_UFirst, _Uend(_Range));
@@ -6379,7 +6299,7 @@ void _Random_shuffle1(_RanIt _First, _RanIt _Last, _RngFn& _RngFunc) {
63796299_EXPORT_STD template <class _RanIt, class _Urng>
63806300void shuffle(_RanIt _First, _RanIt _Last, _Urng&& _Func) { // shuffle [_First, _Last) using URNG _Func
63816301 using _Urng0 = remove_reference_t<_Urng>;
6382- _Rng_from_urng_v1_or_v2 <_Iter_diff_t<_RanIt>, _Urng0> _RngFunc(_Func);
6302+ _Rng_from_urng_v2 <_Iter_diff_t<_RanIt>, _Urng0> _RngFunc(_Func);
63836303 _STD _Random_shuffle1(_First, _Last, _RngFunc);
63846304}
63856305
@@ -6392,7 +6312,7 @@ namespace ranges {
63926312 _STATIC_CALL_OPERATOR _It operator()(_It _First, _Se _Last, _Urng&& _Func) _CONST_CALL_OPERATOR {
63936313 _STD _Adl_verify_range(_First, _Last);
63946314
6395- _Rng_from_urng_v1_or_v2 <iter_difference_t<_It>, remove_reference_t<_Urng>> _RngFunc(_Func);
6315+ _Rng_from_urng_v2 <iter_difference_t<_It>, remove_reference_t<_Urng>> _RngFunc(_Func);
63966316 auto _UResult = _Shuffle_unchecked(
63976317 _RANGES _Unwrap_iter<_Se>(_STD move(_First)), _RANGES _Unwrap_sent<_It>(_STD move(_Last)), _RngFunc);
63986318
@@ -6403,7 +6323,7 @@ namespace ranges {
64036323 template <random_access_range _Rng, class _Urng>
64046324 requires permutable<iterator_t<_Rng>> && uniform_random_bit_generator<remove_reference_t<_Urng>>
64056325 _STATIC_CALL_OPERATOR borrowed_iterator_t<_Rng> operator()(_Rng&& _Range, _Urng&& _Func) _CONST_CALL_OPERATOR {
6406- _Rng_from_urng_v1_or_v2 <range_difference_t<_Rng>, remove_reference_t<_Urng>> _RngFunc(_Func);
6326+ _Rng_from_urng_v2 <range_difference_t<_Rng>, remove_reference_t<_Urng>> _RngFunc(_Func);
64076327
64086328 return _RANGES _Rewrap_iterator(_Range, _Shuffle_unchecked(_Ubegin(_Range), _Uend(_Range), _RngFunc));
64096329 }
0 commit comments