1*4bdff4beSrobert //===----------------------------------------------------------------------===// 2*4bdff4beSrobert // 3*4bdff4beSrobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*4bdff4beSrobert // See https://llvm.org/LICENSE.txt for license information. 5*4bdff4beSrobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*4bdff4beSrobert // 7*4bdff4beSrobert //===----------------------------------------------------------------------===// 8*4bdff4beSrobert 9*4bdff4beSrobert #ifndef _LIBCPP___RANDOM_GENERATE_CANONICAL_H 10*4bdff4beSrobert #define _LIBCPP___RANDOM_GENERATE_CANONICAL_H 11*4bdff4beSrobert 12*4bdff4beSrobert #include <__config> 13*4bdff4beSrobert #include <__random/log2.h> 14*4bdff4beSrobert #include <cstdint> 15*4bdff4beSrobert #include <initializer_list> 16*4bdff4beSrobert #include <limits> 17*4bdff4beSrobert 18*4bdff4beSrobert #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 19*4bdff4beSrobert # pragma GCC system_header 20*4bdff4beSrobert #endif 21*4bdff4beSrobert 22*4bdff4beSrobert _LIBCPP_PUSH_MACROS 23*4bdff4beSrobert #include <__undef_macros> 24*4bdff4beSrobert 25*4bdff4beSrobert _LIBCPP_BEGIN_NAMESPACE_STD 26*4bdff4beSrobert 27*4bdff4beSrobert // generate_canonical 28*4bdff4beSrobert 29*4bdff4beSrobert template<class _RealType, size_t __bits, class _URNG> 30*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _RealType generate_canonical(_URNG & __g)31*4bdff4beSrobertgenerate_canonical(_URNG& __g) 32*4bdff4beSrobert { 33*4bdff4beSrobert const size_t _Dt = numeric_limits<_RealType>::digits; 34*4bdff4beSrobert const size_t __b = _Dt < __bits ? _Dt : __bits; 35*4bdff4beSrobert #ifdef _LIBCPP_CXX03_LANG 36*4bdff4beSrobert const size_t __logR = __log2<uint64_t, _URNG::_Max - _URNG::_Min + uint64_t(1)>::value; 37*4bdff4beSrobert #else 38*4bdff4beSrobert const size_t __logR = __log2<uint64_t, _URNG::max() - _URNG::min() + uint64_t(1)>::value; 39*4bdff4beSrobert #endif 40*4bdff4beSrobert const size_t __k = __b / __logR + (__b % __logR != 0) + (__b == 0); 41*4bdff4beSrobert const _RealType _Rp = static_cast<_RealType>(_URNG::max() - _URNG::min()) + _RealType(1); 42*4bdff4beSrobert _RealType __base = _Rp; 43*4bdff4beSrobert _RealType _Sp = __g() - _URNG::min(); 44*4bdff4beSrobert for (size_t __i = 1; __i < __k; ++__i, __base *= _Rp) 45*4bdff4beSrobert _Sp += (__g() - _URNG::min()) * __base; 46*4bdff4beSrobert return _Sp / __base; 47*4bdff4beSrobert } 48*4bdff4beSrobert 49*4bdff4beSrobert _LIBCPP_END_NAMESPACE_STD 50*4bdff4beSrobert 51*4bdff4beSrobert _LIBCPP_POP_MACROS 52*4bdff4beSrobert 53*4bdff4beSrobert #endif // _LIBCPP___RANDOM_GENERATE_CANONICAL_H 54