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 countr_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::countr_zero(T())), int); 35e130fbe2SArthur O'Dwyer ASSERT_NOEXCEPT(std::countr_zero(T())); 36e130fbe2SArthur O'Dwyer T max = std::numeric_limits<T>::max(); 37a5c3485aSMarshall Clow 38e130fbe2SArthur O'Dwyer assert(std::countr_zero(T(0)) == std::numeric_limits<T>::digits); 39e130fbe2SArthur O'Dwyer assert(std::countr_zero(T(1)) == 0); 40e130fbe2SArthur O'Dwyer assert(std::countr_zero(T(2)) == 1); 41e130fbe2SArthur O'Dwyer assert(std::countr_zero(T(3)) == 0); 42e130fbe2SArthur O'Dwyer assert(std::countr_zero(T(4)) == 2); 43e130fbe2SArthur O'Dwyer assert(std::countr_zero(T(5)) == 0); 44e130fbe2SArthur O'Dwyer assert(std::countr_zero(T(6)) == 1); 45e130fbe2SArthur O'Dwyer assert(std::countr_zero(T(7)) == 0); 46e130fbe2SArthur O'Dwyer assert(std::countr_zero(T(8)) == 3); 47e130fbe2SArthur O'Dwyer assert(std::countr_zero(T(9)) == 0); 48a5c3485aSMarshall Clow assert(std::countr_zero(T(126)) == 1); 49a5c3485aSMarshall Clow assert(std::countr_zero(T(127)) == 0); 50a5c3485aSMarshall Clow assert(std::countr_zero(T(128)) == 7); 51a5c3485aSMarshall Clow assert(std::countr_zero(T(129)) == 0); 52a5c3485aSMarshall Clow assert(std::countr_zero(T(130)) == 1); 53e130fbe2SArthur O'Dwyer assert(std::countr_zero(max) == 0); 54e130fbe2SArthur O'Dwyer 558f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 56e130fbe2SArthur O'Dwyer if constexpr (std::is_same_v<T, __uint128_t>) { 57e130fbe2SArthur O'Dwyer T val = T(128) << 32; 58e130fbe2SArthur O'Dwyer assert(std::countr_zero(val-1) == 0); 59e130fbe2SArthur O'Dwyer assert(std::countr_zero(val) == 39); 60e130fbe2SArthur O'Dwyer assert(std::countr_zero(val+1) == 0); 61e130fbe2SArthur O'Dwyer val <<= 60; 62e130fbe2SArthur O'Dwyer assert(std::countr_zero(val-1) == 0); 63e130fbe2SArthur O'Dwyer assert(std::countr_zero(val) == 99); 64e130fbe2SArthur O'Dwyer assert(std::countr_zero(val+1) == 0); 65e130fbe2SArthur O'Dwyer } 66e130fbe2SArthur O'Dwyer #endif 67e130fbe2SArthur O'Dwyer 68e130fbe2SArthur O'Dwyer return true; 69a5c3485aSMarshall Clow } 70a5c3485aSMarshall Clow 71504bc07dSLouis Dionne int main(int, char**) 72a5c3485aSMarshall Clow { 73a5c3485aSMarshall Clow { 74a5c3485aSMarshall Clow auto lambda = [](auto x) -> decltype(std::countr_zero(x)) {}; 75a5c3485aSMarshall Clow using L = decltype(lambda); 76a5c3485aSMarshall Clow 77e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, signed char>); 78e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, short>); 79e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, int>); 80e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, long>); 81e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, long long>); 828f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 83e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, __int128_t>); 84a5c3485aSMarshall Clow #endif 85a5c3485aSMarshall Clow 86bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int8_t>); 87bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int16_t>); 88bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int32_t>); 89bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int64_t>); 9092fc93e1SMark de Wever static_assert(!std::is_invocable_v<L, std::intmax_t>); 91d59a43feSMark de Wever static_assert(!std::is_invocable_v<L, std::intptr_t>); 92d8681356SMark de Wever static_assert(!std::is_invocable_v<L, std::ptrdiff_t>); 93e130fbe2SArthur O'Dwyer 94e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, bool>); 95e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char>); 96e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, wchar_t>); 979027887eSMark de Wever #ifndef TEST_HAS_NO_CHAR8_T 98e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char8_t>); 99e130fbe2SArthur O'Dwyer #endif 100e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char16_t>); 101e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char32_t>); 102e130fbe2SArthur O'Dwyer 103e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, A>); 104e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, A*>); 105e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, E1>); 106e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, E2>); 107a5c3485aSMarshall Clow } 108a5c3485aSMarshall Clow 109e130fbe2SArthur O'Dwyer static_assert(test<unsigned char>()); 110e130fbe2SArthur O'Dwyer static_assert(test<unsigned short>()); 111e130fbe2SArthur O'Dwyer static_assert(test<unsigned int>()); 112e130fbe2SArthur O'Dwyer static_assert(test<unsigned long>()); 113e130fbe2SArthur O'Dwyer static_assert(test<unsigned long long>()); 1148f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 115e130fbe2SArthur O'Dwyer static_assert(test<__uint128_t>()); 116a5c3485aSMarshall Clow #endif 117bd5d0feeSMark de Wever static_assert(test<std::uint8_t>()); 118bd5d0feeSMark de Wever static_assert(test<std::uint16_t>()); 119da79d6e1SMark de Wever static_assert(test<std::uint32_t>()); 120bd5d0feeSMark de Wever static_assert(test<std::uint64_t>()); 12192fc93e1SMark de Wever static_assert(test<std::uintmax_t>()); 122d59a43feSMark de Wever static_assert(test<std::uintptr_t>()); 123fb855eb9SMark de Wever static_assert(test<std::size_t>()); 124a5c3485aSMarshall Clow 125e130fbe2SArthur O'Dwyer test<unsigned char>(); 126e130fbe2SArthur O'Dwyer test<unsigned short>(); 127e130fbe2SArthur O'Dwyer test<unsigned int>(); 128e130fbe2SArthur O'Dwyer test<unsigned long>(); 129e130fbe2SArthur O'Dwyer test<unsigned long long>(); 1308f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 131e130fbe2SArthur O'Dwyer test<__uint128_t>(); 132a5c3485aSMarshall Clow #endif 133bd5d0feeSMark de Wever test<std::uint8_t>(); 134bd5d0feeSMark de Wever test<std::uint16_t>(); 135da79d6e1SMark de Wever test<std::uint32_t>(); 136bd5d0feeSMark de Wever test<std::uint64_t>(); 13792fc93e1SMark de Wever test<std::uintmax_t>(); 138d59a43feSMark de Wever test<std::uintptr_t>(); 139fb855eb9SMark de Wever test<std::size_t>(); 140a5c3485aSMarshall Clow 141504bc07dSLouis Dionne return 0; 142a5c3485aSMarshall Clow } 143