1a5c3485aSMarshall Clow //===----------------------------------------------------------------------===// 2a5c3485aSMarshall Clow // 31ee41b41SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 41ee41b41SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 51ee41b41SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a5c3485aSMarshall Clow // 7a5c3485aSMarshall Clow //===----------------------------------------------------------------------===// 81ee41b41SNikolas Klauser 931cbe0f2SLouis Dionne // UNSUPPORTED: c++03, c++11, c++14, c++17 10a5c3485aSMarshall Clow 11a5c3485aSMarshall Clow // template <class T> 12a5c3485aSMarshall Clow // constexpr int countl_zero(T x) noexcept; 13a5c3485aSMarshall Clow 14e130fbe2SArthur O'Dwyer // Constraints: T is an unsigned integer type 15a5c3485aSMarshall Clow // Returns: The number of consecutive 0 bits, starting from the most significant bit. 16a5c3485aSMarshall Clow // [ Note: Returns N if x == 0. ] 17a5c3485aSMarshall Clow 18a5c3485aSMarshall Clow #include <bit> 19e130fbe2SArthur O'Dwyer #include <cassert> 20*d6832a61SLouis Dionne #include <cstddef> 21a5c3485aSMarshall Clow #include <cstdint> 2286aac87fSNikolas Klauser #include <limits> 23a5c3485aSMarshall Clow #include <type_traits> 24a5c3485aSMarshall Clow 25a5c3485aSMarshall Clow #include "test_macros.h" 26a5c3485aSMarshall Clow 27e130fbe2SArthur O'Dwyer struct A {}; 28a5c3485aSMarshall Clow enum E1 : unsigned char { rEd }; 29a5c3485aSMarshall Clow enum class E2 : unsigned char { red }; 30a5c3485aSMarshall Clow 31e130fbe2SArthur O'Dwyer template <class T> 32e130fbe2SArthur O'Dwyer constexpr bool test() 33a5c3485aSMarshall Clow { 34e130fbe2SArthur O'Dwyer ASSERT_SAME_TYPE(decltype(std::countl_zero(T())), int); 35e130fbe2SArthur O'Dwyer ASSERT_NOEXCEPT(std::countl_zero(T())); 36e130fbe2SArthur O'Dwyer T max = std::numeric_limits<T>::max(); 37e130fbe2SArthur O'Dwyer int dig = std::numeric_limits<T>::digits; 38a5c3485aSMarshall Clow 39e130fbe2SArthur O'Dwyer assert(std::countl_zero(T(0)) == dig); 40e130fbe2SArthur O'Dwyer assert(std::countl_zero(T(1)) == dig - 1); 41e130fbe2SArthur O'Dwyer assert(std::countl_zero(T(2)) == dig - 2); 42e130fbe2SArthur O'Dwyer assert(std::countl_zero(T(3)) == dig - 2); 43e130fbe2SArthur O'Dwyer assert(std::countl_zero(T(4)) == dig - 3); 44e130fbe2SArthur O'Dwyer assert(std::countl_zero(T(5)) == dig - 3); 45e130fbe2SArthur O'Dwyer assert(std::countl_zero(T(6)) == dig - 3); 46e130fbe2SArthur O'Dwyer assert(std::countl_zero(T(7)) == dig - 3); 47e130fbe2SArthur O'Dwyer assert(std::countl_zero(T(8)) == dig - 4); 48e130fbe2SArthur O'Dwyer assert(std::countl_zero(T(9)) == dig - 4); 49a5c3485aSMarshall Clow assert(std::countl_zero(T(127)) == dig - 7); 50a5c3485aSMarshall Clow assert(std::countl_zero(T(128)) == dig - 8); 51e130fbe2SArthur O'Dwyer assert(std::countl_zero(max) == 0); 52e130fbe2SArthur O'Dwyer 538f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 54e130fbe2SArthur O'Dwyer if constexpr (std::is_same_v<T, __uint128_t>) { 55e130fbe2SArthur O'Dwyer T val = T(128) << 32; 56e130fbe2SArthur O'Dwyer assert(std::countl_zero(val-1) == 89); 57e130fbe2SArthur O'Dwyer assert(std::countl_zero(val) == 88); 58e130fbe2SArthur O'Dwyer assert(std::countl_zero(val+1) == 88); 59e130fbe2SArthur O'Dwyer val <<= 60; 60e130fbe2SArthur O'Dwyer assert(std::countl_zero(val-1) == 29); 61e130fbe2SArthur O'Dwyer assert(std::countl_zero(val) == 28); 62e130fbe2SArthur O'Dwyer assert(std::countl_zero(val+1) == 28); 63e130fbe2SArthur O'Dwyer } 64e130fbe2SArthur O'Dwyer #endif 65e130fbe2SArthur O'Dwyer 66e130fbe2SArthur O'Dwyer return true; 67a5c3485aSMarshall Clow } 68a5c3485aSMarshall Clow 69504bc07dSLouis Dionne int main(int, char**) 70a5c3485aSMarshall Clow { 71a5c3485aSMarshall Clow { 72a5c3485aSMarshall Clow auto lambda = [](auto x) -> decltype(std::countl_zero(x)) {}; 73a5c3485aSMarshall Clow using L = decltype(lambda); 74a5c3485aSMarshall Clow 75e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, signed char>); 76e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, short>); 77e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, int>); 78e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, long>); 79e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, long long>); 808f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 81e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, __int128_t>); 82a5c3485aSMarshall Clow #endif 83a5c3485aSMarshall Clow 84bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int8_t>); 85bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int16_t>); 86bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int32_t>); 87bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int64_t>); 8892fc93e1SMark de Wever static_assert(!std::is_invocable_v<L, std::intmax_t>); 89d59a43feSMark de Wever static_assert(!std::is_invocable_v<L, std::intptr_t>); 90d8681356SMark de Wever static_assert(!std::is_invocable_v<L, std::ptrdiff_t>); 91e130fbe2SArthur O'Dwyer 92e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, bool>); 93e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char>); 94e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, wchar_t>); 959027887eSMark de Wever #ifndef TEST_HAS_NO_CHAR8_T 96e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char8_t>); 97e130fbe2SArthur O'Dwyer #endif 98e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char16_t>); 99e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char32_t>); 100e130fbe2SArthur O'Dwyer 101e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, A>); 102e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, A*>); 103e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, E1>); 104e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, E2>); 105a5c3485aSMarshall Clow } 106a5c3485aSMarshall Clow 107e130fbe2SArthur O'Dwyer static_assert(test<unsigned char>()); 108e130fbe2SArthur O'Dwyer static_assert(test<unsigned short>()); 109e130fbe2SArthur O'Dwyer static_assert(test<unsigned int>()); 110e130fbe2SArthur O'Dwyer static_assert(test<unsigned long>()); 111e130fbe2SArthur O'Dwyer static_assert(test<unsigned long long>()); 1128f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 113e130fbe2SArthur O'Dwyer static_assert(test<__uint128_t>()); 114a5c3485aSMarshall Clow #endif 115bd5d0feeSMark de Wever static_assert(test<std::uint8_t>()); 116bd5d0feeSMark de Wever static_assert(test<std::uint16_t>()); 117da79d6e1SMark de Wever static_assert(test<std::uint32_t>()); 118bd5d0feeSMark de Wever static_assert(test<std::uint64_t>()); 11992fc93e1SMark de Wever static_assert(test<std::uintmax_t>()); 120d59a43feSMark de Wever static_assert(test<std::uintptr_t>()); 121fb855eb9SMark de Wever static_assert(test<std::size_t>()); 122a5c3485aSMarshall Clow 123e130fbe2SArthur O'Dwyer test<unsigned char>(); 124e130fbe2SArthur O'Dwyer test<unsigned short>(); 125e130fbe2SArthur O'Dwyer test<unsigned int>(); 126e130fbe2SArthur O'Dwyer test<unsigned long>(); 127e130fbe2SArthur O'Dwyer test<unsigned long long>(); 1288f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 129e130fbe2SArthur O'Dwyer test<__uint128_t>(); 130a5c3485aSMarshall Clow #endif 131bd5d0feeSMark de Wever test<std::uint8_t>(); 132bd5d0feeSMark de Wever test<std::uint16_t>(); 133da79d6e1SMark de Wever test<std::uint32_t>(); 134bd5d0feeSMark de Wever test<std::uint64_t>(); 13592fc93e1SMark de Wever test<std::uintmax_t>(); 136d59a43feSMark de Wever test<std::uintptr_t>(); 137fb855eb9SMark de Wever test<std::size_t>(); 138a5c3485aSMarshall Clow 139504bc07dSLouis Dionne return 0; 140a5c3485aSMarshall Clow } 141