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 popcount(T x) noexcept; 13a5c3485aSMarshall Clow 14e130fbe2SArthur O'Dwyer // Constraints: T is an unsigned integer type 15a5c3485aSMarshall Clow // Returns: The number of bits set to one in the value of x. 16a5c3485aSMarshall Clow 17a5c3485aSMarshall Clow #include <bit> 18e130fbe2SArthur O'Dwyer #include <cassert> 19*d6832a61SLouis Dionne #include <cstddef> 20a5c3485aSMarshall Clow #include <cstdint> 2186aac87fSNikolas Klauser #include <limits> 22a5c3485aSMarshall Clow #include <type_traits> 23a5c3485aSMarshall Clow 24a5c3485aSMarshall Clow #include "test_macros.h" 25a5c3485aSMarshall Clow 26e130fbe2SArthur O'Dwyer struct A {}; 27a5c3485aSMarshall Clow enum E1 : unsigned char { rEd }; 28a5c3485aSMarshall Clow enum class E2 : unsigned char { red }; 29a5c3485aSMarshall Clow 30e130fbe2SArthur O'Dwyer template <class T> 31e130fbe2SArthur O'Dwyer constexpr bool test() 32a5c3485aSMarshall Clow { 33e130fbe2SArthur O'Dwyer ASSERT_SAME_TYPE(decltype(std::popcount(T())), int); 34e130fbe2SArthur O'Dwyer ASSERT_NOEXCEPT(std::popcount(T())); 35e130fbe2SArthur O'Dwyer T max = std::numeric_limits<T>::max(); 36a5c3485aSMarshall Clow 37e130fbe2SArthur O'Dwyer assert(std::popcount(T(0)) == 0); 38e130fbe2SArthur O'Dwyer assert(std::popcount(T(1)) == 1); 39e130fbe2SArthur O'Dwyer assert(std::popcount(T(2)) == 1); 40e130fbe2SArthur O'Dwyer assert(std::popcount(T(3)) == 2); 41e130fbe2SArthur O'Dwyer assert(std::popcount(T(4)) == 1); 42e130fbe2SArthur O'Dwyer assert(std::popcount(T(5)) == 2); 43e130fbe2SArthur O'Dwyer assert(std::popcount(T(6)) == 2); 44e130fbe2SArthur O'Dwyer assert(std::popcount(T(7)) == 3); 45e130fbe2SArthur O'Dwyer assert(std::popcount(T(8)) == 1); 46e130fbe2SArthur O'Dwyer assert(std::popcount(T(9)) == 2); 47a5c3485aSMarshall Clow assert(std::popcount(T(121)) == 5); 48a5c3485aSMarshall Clow assert(std::popcount(T(127)) == 7); 49a5c3485aSMarshall Clow assert(std::popcount(T(128)) == 1); 50a5c3485aSMarshall Clow assert(std::popcount(T(130)) == 2); 51e130fbe2SArthur O'Dwyer assert(std::popcount(T(max >> 1)) == std::numeric_limits<T>::digits - 1); 52e130fbe2SArthur O'Dwyer assert(std::popcount(T(max - 1)) == std::numeric_limits<T>::digits - 1); 53e130fbe2SArthur O'Dwyer assert(std::popcount(max) == std::numeric_limits<T>::digits); 54a5c3485aSMarshall Clow 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 = 128; 58e130fbe2SArthur O'Dwyer assert(std::popcount(val-1) == 7); 59e130fbe2SArthur O'Dwyer assert(std::popcount(val) == 1); 60e130fbe2SArthur O'Dwyer assert(std::popcount(val+1) == 2); 61a5c3485aSMarshall Clow val <<= 32; 62a5c3485aSMarshall Clow assert(std::popcount(val-1) == 39); 63a5c3485aSMarshall Clow assert(std::popcount(val) == 1); 64a5c3485aSMarshall Clow assert(std::popcount(val+1) == 2); 65e130fbe2SArthur O'Dwyer val <<= 60; 66e130fbe2SArthur O'Dwyer assert(std::popcount(val-1) == 99); 67a5c3485aSMarshall Clow assert(std::popcount(val) == 1); 68a5c3485aSMarshall Clow assert(std::popcount(val+1) == 2); 69e130fbe2SArthur O'Dwyer 70e130fbe2SArthur O'Dwyer T x = T(1) << 63; 71e130fbe2SArthur O'Dwyer T y = T(1) << 64; 72e130fbe2SArthur O'Dwyer assert(std::popcount(x) == 1); 73e130fbe2SArthur O'Dwyer assert(std::popcount(y) == 1); 74e130fbe2SArthur O'Dwyer assert(std::popcount(x+y) == 2); 75a5c3485aSMarshall Clow } 76a5c3485aSMarshall Clow #endif 77504bc07dSLouis Dionne 78e130fbe2SArthur O'Dwyer return true; 79e130fbe2SArthur O'Dwyer } 80e130fbe2SArthur O'Dwyer 81e130fbe2SArthur O'Dwyer int main(int, char**) 82e130fbe2SArthur O'Dwyer { 83e130fbe2SArthur O'Dwyer { 84e130fbe2SArthur O'Dwyer auto lambda = [](auto x) -> decltype(std::popcount(x)) {}; 85e130fbe2SArthur O'Dwyer using L = decltype(lambda); 86e130fbe2SArthur O'Dwyer 87e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, signed char>); 88e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, short>); 89e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, int>); 90e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, long>); 91e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, long long>); 928f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 93e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, __int128_t>); 94e130fbe2SArthur O'Dwyer #endif 95e130fbe2SArthur O'Dwyer 96bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int8_t>); 97bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int16_t>); 98bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int32_t>); 99bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int64_t>); 10092fc93e1SMark de Wever static_assert(!std::is_invocable_v<L, std::intmax_t>); 101d59a43feSMark de Wever static_assert(!std::is_invocable_v<L, std::intptr_t>); 102d8681356SMark de Wever static_assert(!std::is_invocable_v<L, std::ptrdiff_t>); 103e130fbe2SArthur O'Dwyer 104e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, bool>); 105e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char>); 106e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, wchar_t>); 1079027887eSMark de Wever #ifndef TEST_HAS_NO_CHAR8_T 108e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char8_t>); 109e130fbe2SArthur O'Dwyer #endif 110e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char16_t>); 111e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char32_t>); 112e130fbe2SArthur O'Dwyer 113e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, A>); 114e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, A*>); 115e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, E1>); 116e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, E2>); 117e130fbe2SArthur O'Dwyer } 118e130fbe2SArthur O'Dwyer 119e130fbe2SArthur O'Dwyer static_assert(test<unsigned char>()); 120e130fbe2SArthur O'Dwyer static_assert(test<unsigned short>()); 121e130fbe2SArthur O'Dwyer static_assert(test<unsigned int>()); 122e130fbe2SArthur O'Dwyer static_assert(test<unsigned long>()); 123e130fbe2SArthur O'Dwyer static_assert(test<unsigned long long>()); 1248f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 125e130fbe2SArthur O'Dwyer static_assert(test<__uint128_t>()); 126e130fbe2SArthur O'Dwyer #endif 127bd5d0feeSMark de Wever static_assert(test<std::uint8_t>()); 128bd5d0feeSMark de Wever static_assert(test<std::uint16_t>()); 129da79d6e1SMark de Wever static_assert(test<std::uint32_t>()); 130bd5d0feeSMark de Wever static_assert(test<std::uint64_t>()); 13192fc93e1SMark de Wever static_assert(test<std::uintmax_t>()); 132d59a43feSMark de Wever static_assert(test<std::uintptr_t>()); 133fb855eb9SMark de Wever static_assert(test<std::size_t>()); 134e130fbe2SArthur O'Dwyer 135e130fbe2SArthur O'Dwyer test<unsigned char>(); 136e130fbe2SArthur O'Dwyer test<unsigned short>(); 137e130fbe2SArthur O'Dwyer test<unsigned int>(); 138e130fbe2SArthur O'Dwyer test<unsigned long>(); 139e130fbe2SArthur O'Dwyer test<unsigned long long>(); 1408f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 141e130fbe2SArthur O'Dwyer test<__uint128_t>(); 142e130fbe2SArthur O'Dwyer #endif 143bd5d0feeSMark de Wever test<std::uint8_t>(); 144bd5d0feeSMark de Wever test<std::uint16_t>(); 145da79d6e1SMark de Wever test<std::uint32_t>(); 146bd5d0feeSMark de Wever test<std::uint64_t>(); 14792fc93e1SMark de Wever test<std::uintmax_t>(); 148d59a43feSMark de Wever test<std::uintptr_t>(); 149fb855eb9SMark de Wever test<std::size_t>(); 150e130fbe2SArthur O'Dwyer 151504bc07dSLouis Dionne return 0; 152a5c3485aSMarshall Clow } 153