1344cef66SArthur O'Dwyer //===----------------------------------------------------------------------===// 2344cef66SArthur O'Dwyer // 3344cef66SArthur O'Dwyer // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4344cef66SArthur O'Dwyer // See https://llvm.org/LICENSE.txt for license information. 5344cef66SArthur O'Dwyer // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6344cef66SArthur O'Dwyer // 7344cef66SArthur O'Dwyer //===----------------------------------------------------------------------===// 8344cef66SArthur O'Dwyer 9344cef66SArthur O'Dwyer #ifndef _LIBCPP___RANDOM_GENERATE_CANONICAL_H 10344cef66SArthur O'Dwyer #define _LIBCPP___RANDOM_GENERATE_CANONICAL_H 11344cef66SArthur O'Dwyer 12344cef66SArthur O'Dwyer #include <__config> 13344cef66SArthur O'Dwyer #include <__random/log2.h> 14344cef66SArthur O'Dwyer #include <cstdint> 15344cef66SArthur O'Dwyer #include <initializer_list> 16344cef66SArthur O'Dwyer #include <limits> 17344cef66SArthur O'Dwyer 18344cef66SArthur O'Dwyer #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 19344cef66SArthur O'Dwyer # pragma GCC system_header 20344cef66SArthur O'Dwyer #endif 21344cef66SArthur O'Dwyer 22344cef66SArthur O'Dwyer _LIBCPP_PUSH_MACROS 23344cef66SArthur O'Dwyer #include <__undef_macros> 24344cef66SArthur O'Dwyer 25344cef66SArthur O'Dwyer _LIBCPP_BEGIN_NAMESPACE_STD 26344cef66SArthur O'Dwyer 27344cef66SArthur O'Dwyer // generate_canonical 28344cef66SArthur O'Dwyer 29344cef66SArthur O'Dwyer template <class _RealType, size_t __bits, class _URNG> generate_canonical(_URNG & __g)30*9783f28cSLouis Dionne_LIBCPP_HIDE_FROM_ABI _RealType generate_canonical(_URNG& __g) { 31d05f8895SNikolas Klauser const size_t __dt = numeric_limits<_RealType>::digits; 32d05f8895SNikolas Klauser const size_t __b = __dt < __bits ? __dt : __bits; 33344cef66SArthur O'Dwyer #ifdef _LIBCPP_CXX03_LANG 34d05f8895SNikolas Klauser const size_t __log_r = __log2<uint64_t, _URNG::_Max - _URNG::_Min + uint64_t(1)>::value; 35344cef66SArthur O'Dwyer #else 36d05f8895SNikolas Klauser const size_t __log_r = __log2<uint64_t, _URNG::max() - _URNG::min() + uint64_t(1)>::value; 37344cef66SArthur O'Dwyer #endif 38d05f8895SNikolas Klauser const size_t __k = __b / __log_r + (__b % __log_r != 0) + (__b == 0); 39d05f8895SNikolas Klauser const _RealType __rp = static_cast<_RealType>(_URNG::max() - _URNG::min()) + _RealType(1); 40d05f8895SNikolas Klauser _RealType __base = __rp; 41d05f8895SNikolas Klauser _RealType __sp = __g() - _URNG::min(); 42d05f8895SNikolas Klauser for (size_t __i = 1; __i < __k; ++__i, __base *= __rp) 43d05f8895SNikolas Klauser __sp += (__g() - _URNG::min()) * __base; 44d05f8895SNikolas Klauser return __sp / __base; 45344cef66SArthur O'Dwyer } 46344cef66SArthur O'Dwyer 47344cef66SArthur O'Dwyer _LIBCPP_END_NAMESPACE_STD 48344cef66SArthur O'Dwyer 49344cef66SArthur O'Dwyer _LIBCPP_POP_MACROS 50344cef66SArthur O'Dwyer 51344cef66SArthur O'Dwyer #endif // _LIBCPP___RANDOM_GENERATE_CANONICAL_H 52