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_LOG2_H 10344cef66SArthur O'Dwyer #define _LIBCPP___RANDOM_LOG2_H 11344cef66SArthur O'Dwyer 12344cef66SArthur O'Dwyer #include <__config> 13*e99c4906SNikolas Klauser #include <__cstddef/size_t.h> 14e698c595SNikolas Klauser #include <__type_traits/conditional.h> 15344cef66SArthur O'Dwyer 16344cef66SArthur O'Dwyer #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 17344cef66SArthur O'Dwyer # pragma GCC system_header 18344cef66SArthur O'Dwyer #endif 19344cef66SArthur O'Dwyer 20344cef66SArthur O'Dwyer _LIBCPP_BEGIN_NAMESPACE_STD 21344cef66SArthur O'Dwyer 22b254c2e2SFabian Wolff template <class _UIntType, _UIntType _Xp, size_t _Rp> 23b254c2e2SFabian Wolff struct __log2_imp; 24b254c2e2SFabian Wolff 25344cef66SArthur O'Dwyer template <unsigned long long _Xp, size_t _Rp> 269783f28cSLouis Dionne struct __log2_imp<unsigned long long, _Xp, _Rp> { 279783f28cSLouis Dionne static const size_t value = 289783f28cSLouis Dionne _Xp & ((unsigned long long)(1) << _Rp) ? _Rp : __log2_imp<unsigned long long, _Xp, _Rp - 1>::value; 29344cef66SArthur O'Dwyer }; 30344cef66SArthur O'Dwyer 31344cef66SArthur O'Dwyer template <unsigned long long _Xp> 329783f28cSLouis Dionne struct __log2_imp<unsigned long long, _Xp, 0> { 33344cef66SArthur O'Dwyer static const size_t value = 0; 34344cef66SArthur O'Dwyer }; 35344cef66SArthur O'Dwyer 36344cef66SArthur O'Dwyer template <size_t _Rp> 379783f28cSLouis Dionne struct __log2_imp<unsigned long long, 0, _Rp> { 38344cef66SArthur O'Dwyer static const size_t value = _Rp + 1; 39344cef66SArthur O'Dwyer }; 40344cef66SArthur O'Dwyer 41ba87515fSNikolas Klauser #if _LIBCPP_HAS_INT128 42b254c2e2SFabian Wolff 43b254c2e2SFabian Wolff template <__uint128_t _Xp, size_t _Rp> 449783f28cSLouis Dionne struct __log2_imp<__uint128_t, _Xp, _Rp> { 459783f28cSLouis Dionne static const size_t value = 469783f28cSLouis Dionne (_Xp >> 64) ? (64 + __log2_imp<unsigned long long, (_Xp >> 64), 63>::value) 47b254c2e2SFabian Wolff : __log2_imp<unsigned long long, _Xp, 63>::value; 48b254c2e2SFabian Wolff }; 49b254c2e2SFabian Wolff 50ba87515fSNikolas Klauser #endif // _LIBCPP_HAS_INT128 51b254c2e2SFabian Wolff 52344cef66SArthur O'Dwyer template <class _UIntType, _UIntType _Xp> 539783f28cSLouis Dionne struct __log2 { 54b254c2e2SFabian Wolff static const size_t value = __log2_imp< 55ba87515fSNikolas Klauser #if _LIBCPP_HAS_INT128 56ed2d3644SNikolas Klauser __conditional_t<sizeof(_UIntType) <= sizeof(unsigned long long), unsigned long long, __uint128_t>, 57b254c2e2SFabian Wolff #else 58b254c2e2SFabian Wolff unsigned long long, 59ba87515fSNikolas Klauser #endif // _LIBCPP_HAS_INT128 60ed2d3644SNikolas Klauser _Xp, 61ed2d3644SNikolas Klauser sizeof(_UIntType) * __CHAR_BIT__ - 1>::value; 62344cef66SArthur O'Dwyer }; 63344cef66SArthur O'Dwyer 64344cef66SArthur O'Dwyer _LIBCPP_END_NAMESPACE_STD 65344cef66SArthur O'Dwyer 66344cef66SArthur O'Dwyer #endif // _LIBCPP___RANDOM_LOG2_H 67