===================================================================
@@ -3738,12 +3738,40 @@
_DistanceType;
typedef typename std::make_unsigned<_DistanceType>::type __ud_type;
- typedef typename std::uniform_int_distribution<__ud_type> __distr_type;
- typedef typename __distr_type::param_type __p_type;
- __distr_type __d;
+ typedef typename std::remove_reference<_UniformRandomNumberGenerator>::type _Gen;
+ typedef typename std::common_type<typename _Gen::result_type, __ud_type>::type __uc_type;
- for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
- std::iter_swap(__i, __first + __d(__g, __p_type(0, __i - __first)));
+ const __uc_type __urngrange =
+ _Gen::max() - _Gen::min() + 1; // +1 because the generator range is inclusive
+
+ const __uc_type __urange = __uc_type(__last - __first);
+
+ if (__urngrange >= __urange)
+ {
+ const __uc_type __scaling = __urngrange / __urange;
+ const __uc_type __past = __urange * __scaling;
+
+ for (_RandomAccessIterator __i = __first; __i != __last; ++__i)
+ {
+ __uc_type __j;
+ do
+ {
+ __j = __uc_type(__g()) - _Gen::min();
+ }
+ while (__j >= __past);
+
+ std::iter_swap(__i, __first + __j / __scaling);
+ }
+ }
+ else
+ {
+ typedef typename std::uniform_int_distribution<__ud_type> __distr_type;
+ typedef typename __distr_type::param_type __p_type;
+ __distr_type __d;
+
+ for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
+ std::iter_swap(__i, __first + __d(__g, __p_type(0, __i - __first)));
+ }
}
#endif