xref: /llvm-project/libcxx/include/__random/generate_canonical.h (revision 9783f28cbb155e4a8d49c12e1c60ce14dcfaf0c7)
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