11a036e9cSMark de Wever //===----------------------------------------------------------------------===// 21a036e9cSMark de Wever // 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 61a036e9cSMark de Wever // 71a036e9cSMark de Wever //===----------------------------------------------------------------------===// 81ee41b41SNikolas Klauser 91a036e9cSMark de Wever // UNSUPPORTED: c++03, c++11, c++14, c++17 101a036e9cSMark de Wever 111a036e9cSMark de Wever // template <class T> 121a036e9cSMark de Wever // constexpr T bit_floor(T x) noexcept; 131a036e9cSMark de Wever 14e130fbe2SArthur O'Dwyer // Constraints: T is an unsigned integer type 151a036e9cSMark de Wever // Returns: If x == 0, 0; otherwise the maximal value y such that bit_floor(y) is true and y <= x. 161a036e9cSMark de Wever 171a036e9cSMark de Wever #include <bit> 18e130fbe2SArthur O'Dwyer #include <cassert> 19*d6832a61SLouis Dionne #include <cstddef> 201a036e9cSMark de Wever #include <cstdint> 2186aac87fSNikolas Klauser #include <limits> 221a036e9cSMark de Wever #include <type_traits> 231a036e9cSMark de Wever 241a036e9cSMark de Wever #include "test_macros.h" 251a036e9cSMark de Wever 26e130fbe2SArthur O'Dwyer struct A {}; 271a036e9cSMark de Wever enum E1 : unsigned char { rEd }; 281a036e9cSMark de Wever enum class E2 : unsigned char { red }; 291a036e9cSMark de Wever 30e130fbe2SArthur O'Dwyer template <class T> 31e130fbe2SArthur O'Dwyer constexpr bool test() 321a036e9cSMark de Wever { 33e130fbe2SArthur O'Dwyer ASSERT_SAME_TYPE(decltype(std::bit_floor(T())), T); 34e130fbe2SArthur O'Dwyer LIBCPP_ASSERT_NOEXCEPT(std::bit_floor(T())); 35e130fbe2SArthur O'Dwyer T max = std::numeric_limits<T>::max(); 361a036e9cSMark de Wever 37e130fbe2SArthur O'Dwyer assert(std::bit_floor(T(0)) == T(0)); 38e130fbe2SArthur O'Dwyer assert(std::bit_floor(T(1)) == T(1)); 39e130fbe2SArthur O'Dwyer assert(std::bit_floor(T(2)) == T(2)); 40e130fbe2SArthur O'Dwyer assert(std::bit_floor(T(3)) == T(2)); 41e130fbe2SArthur O'Dwyer assert(std::bit_floor(T(4)) == T(4)); 42e130fbe2SArthur O'Dwyer assert(std::bit_floor(T(5)) == T(4)); 43e130fbe2SArthur O'Dwyer assert(std::bit_floor(T(6)) == T(4)); 44e130fbe2SArthur O'Dwyer assert(std::bit_floor(T(7)) == T(4)); 45e130fbe2SArthur O'Dwyer assert(std::bit_floor(T(8)) == T(8)); 46e130fbe2SArthur O'Dwyer assert(std::bit_floor(T(9)) == T(8)); 471a036e9cSMark de Wever assert(std::bit_floor(T(125)) == T(64)); 481a036e9cSMark de Wever assert(std::bit_floor(T(126)) == T(64)); 491a036e9cSMark de Wever assert(std::bit_floor(T(127)) == T(64)); 501a036e9cSMark de Wever assert(std::bit_floor(T(128)) == T(128)); 511a036e9cSMark de Wever assert(std::bit_floor(T(129)) == T(128)); 52e130fbe2SArthur O'Dwyer assert(std::bit_floor(max) == T(max - (max >> 1))); 53e130fbe2SArthur O'Dwyer 548f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 55e130fbe2SArthur O'Dwyer if constexpr (std::is_same_v<T, __uint128_t>) { 56e130fbe2SArthur O'Dwyer T val = T(128) << 32; 57e130fbe2SArthur O'Dwyer assert(std::bit_floor(val-1) == val/2); 58e130fbe2SArthur O'Dwyer assert(std::bit_floor(val) == val); 59e130fbe2SArthur O'Dwyer assert(std::bit_floor(val+1) == val); 60e130fbe2SArthur O'Dwyer val <<= 60; 61e130fbe2SArthur O'Dwyer assert(std::bit_floor(val-1) == val/2); 62e130fbe2SArthur O'Dwyer assert(std::bit_floor(val) == val); 63e130fbe2SArthur O'Dwyer assert(std::bit_floor(val+1) == val); 64e130fbe2SArthur O'Dwyer } 65e130fbe2SArthur O'Dwyer #endif 66e130fbe2SArthur O'Dwyer 67e130fbe2SArthur O'Dwyer return true; 681a036e9cSMark de Wever } 691a036e9cSMark de Wever 701a036e9cSMark de Wever int main(int, char**) 711a036e9cSMark de Wever { 721a036e9cSMark de Wever { 731a036e9cSMark de Wever auto lambda = [](auto x) -> decltype(std::bit_floor(x)) {}; 741a036e9cSMark de Wever using L = decltype(lambda); 751a036e9cSMark de Wever 76e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, signed char>); 77e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, short>); 78e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, int>); 79e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, long>); 80e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, long long>); 818f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 82e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, __int128_t>); 831a036e9cSMark de Wever #endif 841a036e9cSMark de Wever 85bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int8_t>); 86bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int16_t>); 87bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int32_t>); 88bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int64_t>); 8992fc93e1SMark de Wever static_assert(!std::is_invocable_v<L, std::intmax_t>); 90d59a43feSMark de Wever static_assert(!std::is_invocable_v<L, std::intptr_t>); 91d8681356SMark de Wever static_assert(!std::is_invocable_v<L, std::ptrdiff_t>); 92e130fbe2SArthur O'Dwyer 93e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, bool>); 94e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char>); 95e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, wchar_t>); 969027887eSMark de Wever #ifndef TEST_HAS_NO_CHAR8_T 97e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char8_t>); 98e130fbe2SArthur O'Dwyer #endif 99e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char16_t>); 100e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char32_t>); 101e130fbe2SArthur O'Dwyer 102e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, A>); 103e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, A*>); 104e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, E1>); 105e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, E2>); 1061a036e9cSMark de Wever } 1071a036e9cSMark de Wever 108e130fbe2SArthur O'Dwyer static_assert(test<unsigned char>()); 109e130fbe2SArthur O'Dwyer static_assert(test<unsigned short>()); 110e130fbe2SArthur O'Dwyer static_assert(test<unsigned int>()); 111e130fbe2SArthur O'Dwyer static_assert(test<unsigned long>()); 112e130fbe2SArthur O'Dwyer static_assert(test<unsigned long long>()); 1138f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 114e130fbe2SArthur O'Dwyer static_assert(test<__uint128_t>()); 1151a036e9cSMark de Wever #endif 1161a036e9cSMark de Wever 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>()); 1241a036e9cSMark de Wever 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>(); 1321a036e9cSMark de Wever #endif 1331a036e9cSMark de Wever 134bd5d0feeSMark de Wever test<std::uint8_t>(); 135bd5d0feeSMark de Wever test<std::uint16_t>(); 136da79d6e1SMark de Wever test<std::uint32_t>(); 137bd5d0feeSMark de Wever test<std::uint64_t>(); 13892fc93e1SMark de Wever test<std::uintmax_t>(); 139d59a43feSMark de Wever test<std::uintptr_t>(); 140fb855eb9SMark de Wever test<std::size_t>(); 141e130fbe2SArthur O'Dwyer 1421a036e9cSMark de Wever return 0; 1431a036e9cSMark de Wever } 144