mclow.lists updated this revision to Diff 207394. mclow.lists marked an inline comment as done. mclow.lists added a comment.
Updated patch based on Eric's comments. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D51262/new/ https://reviews.llvm.org/D51262 Files: libcxx/include/bit libcxx/test/std/numerics/bit/bit.pow.two/ceil2.fail.cpp libcxx/test/std/numerics/bit/bit.pow.two/ceil2.pass.cpp libcxx/test/std/numerics/bit/bit.pow.two/floor2.pass.cpp libcxx/test/std/numerics/bit/bit.pow.two/ispow2.pass.cpp libcxx/test/std/numerics/bit/bit.pow.two/log2p1.pass.cpp libcxx/test/std/numerics/bit/bitops.count/countl_one.pass.cpp libcxx/test/std/numerics/bit/bitops.count/countl_zero.pass.cpp libcxx/test/std/numerics/bit/bitops.count/countr_one.pass.cpp libcxx/test/std/numerics/bit/bitops.count/countr_zero.pass.cpp libcxx/test/std/numerics/bit/bitops.count/popcount.pass.cpp libcxx/test/std/numerics/bit/bitops.rot/rotl.pass.cpp libcxx/test/std/numerics/bit/bitops.rot/rotr.pass.cpp libcxx/test/std/numerics/bit/nothing_to_do.pass.cpp
Index: libcxx/test/std/numerics/bit/nothing_to_do.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/numerics/bit/nothing_to_do.pass.cpp @@ -0,0 +1,12 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} Index: libcxx/test/std/numerics/bit/bitops.rot/rotr.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/numerics/bit/bitops.rot/rotr.pass.cpp @@ -0,0 +1,181 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// template <class T> +// constexpr int rotr(T x, unsigned int s) noexcept; + +// Remarks: This function shall not participate in overload resolution unless +// T is an unsigned integer type + +#include <bit> +#include <cstdint> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +class A{}; +enum E1 : unsigned char { rEd }; +enum class E2 : unsigned char { red }; + +template <typename T> +constexpr bool constexpr_test() +{ + const T max = std::numeric_limits<T>::max(); + + return std::rotr(T(128), 0) == T(128) + && std::rotr(T(128), 1) == T( 64) + && std::rotr(T(128), 2) == T( 32) + && std::rotr(T(128), 3) == T( 16) + && std::rotr(T(128), 4) == T( 8) + && std::rotr(T(128), 5) == T( 4) + && std::rotr(T(128), 6) == T( 2) + && std::rotr(T(128), 7) == T( 1) + && std::rotr(max, 0) == max + && std::rotr(max, 1) == max + && std::rotr(max, 2) == max + && std::rotr(max, 3) == max + && std::rotr(max, 4) == max + && std::rotr(max, 5) == max + && std::rotr(max, 6) == max + && std::rotr(max, 7) == max + ; +} + + +template <typename T> +void runtime_test() +{ + ASSERT_SAME_TYPE(T, decltype(std::rotr(T(0), 0))); + ASSERT_NOEXCEPT( std::rotr(T(0), 0)); + const T max = std::numeric_limits<T>::max(); + const T val = std::numeric_limits<T>::max() - 1; + + const T uppers [] = { + max, // not used + max - max, // 000 .. 0 + max - (max >> 1), // 800 .. 0 + max - (max >> 2), // C00 .. 0 + max - (max >> 3), // E00 .. 0 + max - (max >> 4), // F00 .. 0 + max - (max >> 5), // F80 .. 0 + max - (max >> 6), // FC0 .. 0 + max - (max >> 7), // FE0 .. 0 + }; + + assert( std::rotr(val, 0) == val); + assert( std::rotr(val, 1) == T((val >> 1) + uppers[1])); + assert( std::rotr(val, 2) == T((val >> 2) + uppers[2])); + assert( std::rotr(val, 3) == T((val >> 3) + uppers[3])); + assert( std::rotr(val, 4) == T((val >> 4) + uppers[4])); + assert( std::rotr(val, 5) == T((val >> 5) + uppers[5])); + assert( std::rotr(val, 6) == T((val >> 6) + uppers[6])); + assert( std::rotr(val, 7) == T((val >> 7) + uppers[7])); +} + +int main() +{ + + { + auto lambda = [](auto x) -> decltype(std::rotr(x, 1U)) {}; + using L = decltype(lambda); + + static_assert( std::is_invocable_v<L, unsigned char>, ""); + static_assert( std::is_invocable_v<L, unsigned int>, ""); + static_assert( std::is_invocable_v<L, unsigned long>, ""); + static_assert( std::is_invocable_v<L, unsigned long long>, ""); + + static_assert( std::is_invocable_v<L, uint8_t>, ""); + static_assert( std::is_invocable_v<L, uint16_t>, ""); + static_assert( std::is_invocable_v<L, uint32_t>, ""); + static_assert( std::is_invocable_v<L, uint64_t>, ""); + static_assert( std::is_invocable_v<L, size_t>, ""); + + static_assert( std::is_invocable_v<L, uintmax_t>, ""); + static_assert( std::is_invocable_v<L, uintptr_t>, ""); + + + static_assert(!std::is_invocable_v<L, int>, ""); + static_assert(!std::is_invocable_v<L, signed int>, ""); + static_assert(!std::is_invocable_v<L, long>, ""); + static_assert(!std::is_invocable_v<L, long long>, ""); + + static_assert(!std::is_invocable_v<L, int8_t>, ""); + static_assert(!std::is_invocable_v<L, int16_t>, ""); + static_assert(!std::is_invocable_v<L, int32_t>, ""); + static_assert(!std::is_invocable_v<L, int64_t>, ""); + static_assert(!std::is_invocable_v<L, ptrdiff_t>, ""); + + static_assert(!std::is_invocable_v<L, bool>, ""); + static_assert(!std::is_invocable_v<L, signed char>, ""); + static_assert(!std::is_invocable_v<L, char16_t>, ""); + static_assert(!std::is_invocable_v<L, char32_t>, ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert( std::is_invocable_v<L, __uint128_t>, ""); + static_assert(!std::is_invocable_v<L, __int128_t>, ""); +#endif + + static_assert(!std::is_invocable_v<L, A, unsigned>, ""); + static_assert(!std::is_invocable_v<L, E1, unsigned>, ""); + static_assert(!std::is_invocable_v<L, E2, unsigned>, ""); + } + + static_assert(constexpr_test<unsigned char>(), ""); + static_assert(constexpr_test<unsigned short>(), ""); + static_assert(constexpr_test<unsigned>(), ""); + static_assert(constexpr_test<unsigned long>(), ""); + static_assert(constexpr_test<unsigned long long>(), ""); + + static_assert(constexpr_test<uint8_t>(), ""); + static_assert(constexpr_test<uint16_t>(), ""); + static_assert(constexpr_test<uint32_t>(), ""); + static_assert(constexpr_test<uint64_t>(), ""); + static_assert(constexpr_test<size_t>(), ""); + static_assert(constexpr_test<uintmax_t>(), ""); + static_assert(constexpr_test<uintptr_t>(), ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert(constexpr_test<__uint128_t>(), ""); +#endif + + + runtime_test<unsigned char>(); + runtime_test<unsigned>(); + runtime_test<unsigned short>(); + runtime_test<unsigned long>(); + runtime_test<unsigned long long>(); + + runtime_test<uint8_t>(); + runtime_test<uint16_t>(); + runtime_test<uint32_t>(); + runtime_test<uint64_t>(); + runtime_test<size_t>(); + runtime_test<uintmax_t>(); + runtime_test<uintptr_t>(); + + +#ifndef _LIBCPP_HAS_NO_INT128 + runtime_test<__uint128_t>(); + + { + __uint128_t val = 168; // 0xA8 (aka 10101000) + + assert( std::rotr(val, 128) == 168); + val <<= 32; + assert( std::rotr(val, 32) == 168); + val <<= 2; + assert( std::rotr(val, 33) == 336); + val <<= 3; + assert( std::rotr(val, 38) == 84); + assert( std::rotr(val, 166) == 84); + } +#endif +} Index: libcxx/test/std/numerics/bit/bitops.rot/rotl.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/numerics/bit/bitops.rot/rotl.pass.cpp @@ -0,0 +1,167 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// template <class T> +// constexpr int rotl(T x, unsigned int s) noexcept; + +// Remarks: This function shall not participate in overload resolution unless +// T is an unsigned integer type + +#include <bit> +#include <cstdint> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +class A{}; +enum E1 : unsigned char { rEd }; +enum class E2 : unsigned char { red }; + +template <typename T> +constexpr bool constexpr_test() +{ + const T max = std::numeric_limits<T>::max(); + return std::rotl(T(1), 0) == T( 1) + && std::rotl(T(1), 1) == T( 2) + && std::rotl(T(1), 2) == T( 4) + && std::rotl(T(1), 3) == T( 8) + && std::rotl(T(1), 4) == T( 16) + && std::rotl(T(1), 5) == T( 32) + && std::rotl(T(1), 6) == T( 64) + && std::rotl(T(1), 7) == T(128) + && std::rotl(max, 0) == max + && std::rotl(max, 1) == max + && std::rotl(max, 2) == max + && std::rotl(max, 3) == max + && std::rotl(max, 4) == max + && std::rotl(max, 5) == max + && std::rotl(max, 6) == max + && std::rotl(max, 7) == max + ; +} + + +template <typename T> +void runtime_test() +{ + ASSERT_SAME_TYPE(T, decltype(std::rotl(T(0), 0))); + ASSERT_NOEXCEPT( std::rotl(T(0), 0)); + const T val = std::numeric_limits<T>::max() - 1; + + assert( std::rotl(val, 0) == val); + assert( std::rotl(val, 1) == T((val << 1) + 1)); + assert( std::rotl(val, 2) == T((val << 2) + 3)); + assert( std::rotl(val, 3) == T((val << 3) + 7)); + assert( std::rotl(val, 4) == T((val << 4) + 15)); + assert( std::rotl(val, 5) == T((val << 5) + 31)); + assert( std::rotl(val, 6) == T((val << 6) + 63)); + assert( std::rotl(val, 7) == T((val << 7) + 127)); +} + +int main() +{ + + { + auto lambda = [](auto x) -> decltype(std::rotl(x, 1U)) {}; + using L = decltype(lambda); + + static_assert( std::is_invocable_v<L, unsigned char>, ""); + static_assert( std::is_invocable_v<L, unsigned int>, ""); + static_assert( std::is_invocable_v<L, unsigned long>, ""); + static_assert( std::is_invocable_v<L, unsigned long long>, ""); + + static_assert( std::is_invocable_v<L, uint8_t>, ""); + static_assert( std::is_invocable_v<L, uint16_t>, ""); + static_assert( std::is_invocable_v<L, uint32_t>, ""); + static_assert( std::is_invocable_v<L, uint64_t>, ""); + static_assert( std::is_invocable_v<L, size_t>, ""); + + static_assert( std::is_invocable_v<L, uintmax_t>, ""); + static_assert( std::is_invocable_v<L, uintptr_t>, ""); + + + static_assert(!std::is_invocable_v<L, int>, ""); + static_assert(!std::is_invocable_v<L, signed int>, ""); + static_assert(!std::is_invocable_v<L, long>, ""); + static_assert(!std::is_invocable_v<L, long long>, ""); + + static_assert(!std::is_invocable_v<L, int8_t>, ""); + static_assert(!std::is_invocable_v<L, int16_t>, ""); + static_assert(!std::is_invocable_v<L, int32_t>, ""); + static_assert(!std::is_invocable_v<L, int64_t>, ""); + static_assert(!std::is_invocable_v<L, ptrdiff_t>, ""); + + static_assert(!std::is_invocable_v<L, bool>, ""); + static_assert(!std::is_invocable_v<L, signed char>, ""); + static_assert(!std::is_invocable_v<L, char16_t>, ""); + static_assert(!std::is_invocable_v<L, char32_t>, ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert( std::is_invocable_v<L, __uint128_t>, ""); + static_assert(!std::is_invocable_v<L, __int128_t>, ""); +#endif + + static_assert(!std::is_invocable_v<L, A>, ""); + static_assert(!std::is_invocable_v<L, E1>, ""); + static_assert(!std::is_invocable_v<L, E2>, ""); + } + + static_assert(constexpr_test<unsigned char>(), ""); + static_assert(constexpr_test<unsigned short>(), ""); + static_assert(constexpr_test<unsigned>(), ""); + static_assert(constexpr_test<unsigned long>(), ""); + static_assert(constexpr_test<unsigned long long>(), ""); + + static_assert(constexpr_test<uint8_t>(), ""); + static_assert(constexpr_test<uint16_t>(), ""); + static_assert(constexpr_test<uint32_t>(), ""); + static_assert(constexpr_test<uint64_t>(), ""); + static_assert(constexpr_test<size_t>(), ""); + static_assert(constexpr_test<uintmax_t>(), ""); + static_assert(constexpr_test<uintptr_t>(), ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert(constexpr_test<__uint128_t>(), ""); +#endif + + + runtime_test<unsigned char>(); + runtime_test<unsigned short>(); + runtime_test<unsigned>(); + runtime_test<unsigned long>(); + runtime_test<unsigned long long>(); + + runtime_test<uint8_t>(); + runtime_test<uint16_t>(); + runtime_test<uint32_t>(); + runtime_test<uint64_t>(); + runtime_test<size_t>(); + runtime_test<uintmax_t>(); + runtime_test<uintptr_t>(); + +#ifndef _LIBCPP_HAS_NO_INT128 + runtime_test<__uint128_t>(); + + { + __uint128_t val = 168; // 0xA8 (aka 10101000) + + assert( std::rotl(val, 128) == 168); + val <<= 32; + assert( std::rotl(val, 96) == 168); + val <<= 2; + assert( std::rotl(val, 95) == 336); + val <<= 3; + assert( std::rotl(val, 90) == 84); + assert( std::rotl(val, 218) == 84); + } +#endif + +} Index: libcxx/test/std/numerics/bit/bitops.count/popcount.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/numerics/bit/bitops.count/popcount.pass.cpp @@ -0,0 +1,167 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// template <class T> +// constexpr int popcount(T x) noexcept; + +// Returns: The number of bits set to one in the value of x. +// +// Remarks: This function shall not participate in overload resolution unless +// T is an unsigned integer type + +#include <bit> +#include <cstdint> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +class A{}; +enum E1 : unsigned char { rEd }; +enum class E2 : unsigned char { red }; + +template <typename T> +constexpr bool constexpr_test() +{ + return std::popcount(T(0)) == 0 + && std::popcount(T(1)) == 1 + && std::popcount(T(2)) == 1 + && std::popcount(T(3)) == 2 + && std::popcount(T(4)) == 1 + && std::popcount(T(5)) == 2 + && std::popcount(T(6)) == 2 + && std::popcount(T(7)) == 3 + && std::popcount(T(8)) == 1 + && std::popcount(T(9)) == 2 + && std::popcount(std::numeric_limits<T>::max()) == std::numeric_limits<T>::digits + ; +} + + +template <typename T> +void runtime_test() +{ + ASSERT_SAME_TYPE(int, decltype(std::popcount(T(0)))); + ASSERT_NOEXCEPT( std::popcount(T(0))); + + assert( std::popcount(T(121)) == 5); + assert( std::popcount(T(122)) == 5); + assert( std::popcount(T(123)) == 6); + assert( std::popcount(T(124)) == 5); + assert( std::popcount(T(125)) == 6); + assert( std::popcount(T(126)) == 6); + assert( std::popcount(T(127)) == 7); + assert( std::popcount(T(128)) == 1); + assert( std::popcount(T(129)) == 2); + assert( std::popcount(T(130)) == 2); +} + +int main() +{ + + { + auto lambda = [](auto x) -> decltype(std::popcount(x)) {}; + using L = decltype(lambda); + + static_assert( std::is_invocable_v<L, unsigned char>, ""); + static_assert( std::is_invocable_v<L, unsigned int>, ""); + static_assert( std::is_invocable_v<L, unsigned long>, ""); + static_assert( std::is_invocable_v<L, unsigned long long>, ""); + + static_assert( std::is_invocable_v<L, uint8_t>, ""); + static_assert( std::is_invocable_v<L, uint16_t>, ""); + static_assert( std::is_invocable_v<L, uint32_t>, ""); + static_assert( std::is_invocable_v<L, uint64_t>, ""); + static_assert( std::is_invocable_v<L, size_t>, ""); + + static_assert( std::is_invocable_v<L, uintmax_t>, ""); + static_assert( std::is_invocable_v<L, uintptr_t>, ""); + + + static_assert(!std::is_invocable_v<L, int>, ""); + static_assert(!std::is_invocable_v<L, signed int>, ""); + static_assert(!std::is_invocable_v<L, long>, ""); + static_assert(!std::is_invocable_v<L, long long>, ""); + + static_assert(!std::is_invocable_v<L, int8_t>, ""); + static_assert(!std::is_invocable_v<L, int16_t>, ""); + static_assert(!std::is_invocable_v<L, int32_t>, ""); + static_assert(!std::is_invocable_v<L, int64_t>, ""); + static_assert(!std::is_invocable_v<L, ptrdiff_t>, ""); + + static_assert(!std::is_invocable_v<L, bool>, ""); + static_assert(!std::is_invocable_v<L, signed char>, ""); + static_assert(!std::is_invocable_v<L, char16_t>, ""); + static_assert(!std::is_invocable_v<L, char32_t>, ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert( std::is_invocable_v<L, __uint128_t>, ""); + static_assert(!std::is_invocable_v<L, __int128_t>, ""); +#endif + + static_assert(!std::is_invocable_v<L, A>, ""); + static_assert(!std::is_invocable_v<L, E1>, ""); + static_assert(!std::is_invocable_v<L, E2>, ""); + } + + static_assert(constexpr_test<unsigned char>(), ""); + static_assert(constexpr_test<unsigned short>(), ""); + static_assert(constexpr_test<unsigned>(), ""); + static_assert(constexpr_test<unsigned long>(), ""); + static_assert(constexpr_test<unsigned long long>(), ""); + + static_assert(constexpr_test<uint8_t>(), ""); + static_assert(constexpr_test<uint16_t>(), ""); + static_assert(constexpr_test<uint32_t>(), ""); + static_assert(constexpr_test<uint64_t>(), ""); + static_assert(constexpr_test<size_t>(), ""); + static_assert(constexpr_test<uintmax_t>(), ""); + static_assert(constexpr_test<uintptr_t>(), ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert(constexpr_test<__uint128_t>(), ""); +#endif + + + runtime_test<unsigned char>(); + runtime_test<unsigned>(); + runtime_test<unsigned short>(); + runtime_test<unsigned long>(); + runtime_test<unsigned long long>(); + + runtime_test<uint8_t>(); + runtime_test<uint16_t>(); + runtime_test<uint32_t>(); + runtime_test<uint64_t>(); + runtime_test<size_t>(); + runtime_test<uintmax_t>(); + runtime_test<uintptr_t>(); + +#ifndef _LIBCPP_HAS_NO_INT128 + runtime_test<__uint128_t>(); + + { + __uint128_t val = 128; + + val <<= 32; + assert( std::popcount(val-1) == 39); + assert( std::popcount(val) == 1); + assert( std::popcount(val+1) == 2); + val <<= 2; + assert( std::popcount(val-1) == 41); + assert( std::popcount(val) == 1); + assert( std::popcount(val+1) == 2); + val <<= 3; + assert( std::popcount(val-1) == 44); + assert( std::popcount(val) == 1); + assert( std::popcount(val+1) == 2); + } +#endif +} Index: libcxx/test/std/numerics/bit/bitops.count/countr_zero.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/numerics/bit/bitops.count/countr_zero.pass.cpp @@ -0,0 +1,169 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// template <class T> +// constexpr int countr_zero(T x) noexcept; + +// Returns: The number of consecutive 0 bits, starting from the most significant bit. +// [ Note: Returns N if x == 0. ] +// +// Remarks: This function shall not participate in overload resolution unless +// T is an unsigned integer type + +#include <bit> +#include <cstdint> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +class A{}; +enum E1 : unsigned char { rEd }; +enum class E2 : unsigned char { red }; + +template <typename T> +constexpr bool constexpr_test() +{ + const int dig = std::numeric_limits<T>::digits; + return std::countr_zero(T(0)) == dig + && std::countr_zero(T(1)) == 0 + && std::countr_zero(T(2)) == 1 + && std::countr_zero(T(3)) == 0 + && std::countr_zero(T(4)) == 2 + && std::countr_zero(T(5)) == 0 + && std::countr_zero(T(6)) == 1 + && std::countr_zero(T(7)) == 0 + && std::countr_zero(T(8)) == 3 + && std::countr_zero(T(9)) == 0 + && std::countr_zero(std::numeric_limits<T>::max()) == 0 + ; +} + + +template <typename T> +void runtime_test() +{ + ASSERT_SAME_TYPE(int, decltype(std::countr_zero(T(0)))); + ASSERT_NOEXCEPT( std::countr_zero(T(0))); + + assert( std::countr_zero(T(121)) == 0); + assert( std::countr_zero(T(122)) == 1); + assert( std::countr_zero(T(123)) == 0); + assert( std::countr_zero(T(124)) == 2); + assert( std::countr_zero(T(125)) == 0); + assert( std::countr_zero(T(126)) == 1); + assert( std::countr_zero(T(127)) == 0); + assert( std::countr_zero(T(128)) == 7); + assert( std::countr_zero(T(129)) == 0); + assert( std::countr_zero(T(130)) == 1); +} + +int main() +{ + + { + auto lambda = [](auto x) -> decltype(std::countr_zero(x)) {}; + using L = decltype(lambda); + + static_assert( std::is_invocable_v<L, unsigned char>, ""); + static_assert( std::is_invocable_v<L, unsigned int>, ""); + static_assert( std::is_invocable_v<L, unsigned long>, ""); + static_assert( std::is_invocable_v<L, unsigned long long>, ""); + + static_assert( std::is_invocable_v<L, uint8_t>, ""); + static_assert( std::is_invocable_v<L, uint16_t>, ""); + static_assert( std::is_invocable_v<L, uint32_t>, ""); + static_assert( std::is_invocable_v<L, uint64_t>, ""); + static_assert( std::is_invocable_v<L, size_t>, ""); + + static_assert( std::is_invocable_v<L, uintmax_t>, ""); + static_assert( std::is_invocable_v<L, uintptr_t>, ""); + + + static_assert(!std::is_invocable_v<L, int>, ""); + static_assert(!std::is_invocable_v<L, signed int>, ""); + static_assert(!std::is_invocable_v<L, long>, ""); + static_assert(!std::is_invocable_v<L, long long>, ""); + + static_assert(!std::is_invocable_v<L, int8_t>, ""); + static_assert(!std::is_invocable_v<L, int16_t>, ""); + static_assert(!std::is_invocable_v<L, int32_t>, ""); + static_assert(!std::is_invocable_v<L, int64_t>, ""); + static_assert(!std::is_invocable_v<L, ptrdiff_t>, ""); + + static_assert(!std::is_invocable_v<L, bool>, ""); + static_assert(!std::is_invocable_v<L, signed char>, ""); + static_assert(!std::is_invocable_v<L, char16_t>, ""); + static_assert(!std::is_invocable_v<L, char32_t>, ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert( std::is_invocable_v<L, __uint128_t>, ""); + static_assert(!std::is_invocable_v<L, __int128_t>, ""); +#endif + + static_assert(!std::is_invocable_v<L, A>, ""); + static_assert(!std::is_invocable_v<L, E1>, ""); + static_assert(!std::is_invocable_v<L, E2>, ""); + } + + static_assert(constexpr_test<unsigned char>(), ""); + static_assert(constexpr_test<unsigned short>(), ""); + static_assert(constexpr_test<unsigned>(), ""); + static_assert(constexpr_test<unsigned long>(), ""); + static_assert(constexpr_test<unsigned long long>(), ""); + + static_assert(constexpr_test<uint8_t>(), ""); + static_assert(constexpr_test<uint16_t>(), ""); + static_assert(constexpr_test<uint32_t>(), ""); + static_assert(constexpr_test<uint64_t>(), ""); + static_assert(constexpr_test<size_t>(), ""); + static_assert(constexpr_test<uintmax_t>(), ""); + static_assert(constexpr_test<uintptr_t>(), ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert(constexpr_test<__uint128_t>(), ""); +#endif + + runtime_test<unsigned char>(); + runtime_test<unsigned>(); + runtime_test<unsigned short>(); + runtime_test<unsigned long>(); + runtime_test<unsigned long long>(); + + runtime_test<uint8_t>(); + runtime_test<uint16_t>(); + runtime_test<uint32_t>(); + runtime_test<uint64_t>(); + runtime_test<size_t>(); + runtime_test<uintmax_t>(); + runtime_test<uintptr_t>(); + +#ifndef _LIBCPP_HAS_NO_INT128 + runtime_test<__uint128_t>(); + + { + __uint128_t val = 128; + + val <<= 32; + assert( std::countr_zero(val-1) == 0); + assert( std::countr_zero(val) == 39); + assert( std::countr_zero(val+1) == 0); + val <<= 2; + assert( std::countr_zero(val-1) == 0); + assert( std::countr_zero(val) == 41); + assert( std::countr_zero(val+1) == 0); + val <<= 3; + assert( std::countr_zero(val-1) == 0); + assert( std::countr_zero(val) == 44); + assert( std::countr_zero(val+1) == 0); + } +#endif + +} Index: libcxx/test/std/numerics/bit/bitops.count/countr_one.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/numerics/bit/bitops.count/countr_one.pass.cpp @@ -0,0 +1,170 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// template <class T> +// constexpr int countr_one(T x) noexcept; + +// Returns: The number of consecutive 1 bits, starting from the least significant bit. +// [ Note: Returns N if x == std::numeric_limits<T>::max(). ] +// +// Remarks: This function shall not participate in overload resolution unless +// T is an unsigned integer type + +#include <bit> +#include <cstdint> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +class A{}; +enum E1 : unsigned char { rEd }; +enum class E2 : unsigned char { red }; + +template <typename T> +constexpr bool constexpr_test() +{ + const int dig = std::numeric_limits<T>::digits; + return std::countr_one(T(0)) == 0 + && std::countr_one(T(1)) == 1 + && std::countr_one(T(2)) == 0 + && std::countr_one(T(3)) == 2 + && std::countr_one(T(4)) == 0 + && std::countr_one(T(5)) == 1 + && std::countr_one(T(6)) == 0 + && std::countr_one(T(7)) == 3 + && std::countr_one(T(8)) == 0 + && std::countr_one(T(9)) == 1 + && std::countr_one(std::numeric_limits<T>::max()) == dig + ; +} + + +template <typename T> +void runtime_test() +{ + ASSERT_SAME_TYPE(int, decltype(std::countr_one(T(0)))); + ASSERT_NOEXCEPT( std::countr_one(T(0))); + + assert( std::countr_one(T(121)) == 1); + assert( std::countr_one(T(122)) == 0); + assert( std::countr_one(T(123)) == 2); + assert( std::countr_one(T(124)) == 0); + assert( std::countr_one(T(125)) == 1); + assert( std::countr_one(T(126)) == 0); + assert( std::countr_one(T(127)) == 7); + assert( std::countr_one(T(128)) == 0); + assert( std::countr_one(T(129)) == 1); + assert( std::countr_one(T(130)) == 0); +} + +int main() +{ + + { + auto lambda = [](auto x) -> decltype(std::countr_one(x)) {}; + using L = decltype(lambda); + + static_assert( std::is_invocable_v<L, unsigned char>, ""); + static_assert( std::is_invocable_v<L, unsigned int>, ""); + static_assert( std::is_invocable_v<L, unsigned long>, ""); + static_assert( std::is_invocable_v<L, unsigned long long>, ""); + + static_assert( std::is_invocable_v<L, uint8_t>, ""); + static_assert( std::is_invocable_v<L, uint16_t>, ""); + static_assert( std::is_invocable_v<L, uint32_t>, ""); + static_assert( std::is_invocable_v<L, uint64_t>, ""); + static_assert( std::is_invocable_v<L, size_t>, ""); + + static_assert( std::is_invocable_v<L, uintmax_t>, ""); + static_assert( std::is_invocable_v<L, uintptr_t>, ""); + + + static_assert(!std::is_invocable_v<L, int>, ""); + static_assert(!std::is_invocable_v<L, signed int>, ""); + static_assert(!std::is_invocable_v<L, long>, ""); + static_assert(!std::is_invocable_v<L, long long>, ""); + + static_assert(!std::is_invocable_v<L, int8_t>, ""); + static_assert(!std::is_invocable_v<L, int16_t>, ""); + static_assert(!std::is_invocable_v<L, int32_t>, ""); + static_assert(!std::is_invocable_v<L, int64_t>, ""); + static_assert(!std::is_invocable_v<L, ptrdiff_t>, ""); + + static_assert(!std::is_invocable_v<L, bool>, ""); + static_assert(!std::is_invocable_v<L, signed char>, ""); + static_assert(!std::is_invocable_v<L, char16_t>, ""); + static_assert(!std::is_invocable_v<L, char32_t>, ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert( std::is_invocable_v<L, __uint128_t>, ""); + static_assert(!std::is_invocable_v<L, __int128_t>, ""); +#endif + + static_assert(!std::is_invocable_v<L, A>, ""); + static_assert(!std::is_invocable_v<L, E1>, ""); + static_assert(!std::is_invocable_v<L, E2>, ""); + } + + static_assert(constexpr_test<unsigned char>(), ""); + static_assert(constexpr_test<unsigned short>(), ""); + static_assert(constexpr_test<unsigned>(), ""); + static_assert(constexpr_test<unsigned long>(), ""); + static_assert(constexpr_test<unsigned long long>(), ""); + + static_assert(constexpr_test<uint8_t>(), ""); + static_assert(constexpr_test<uint16_t>(), ""); + static_assert(constexpr_test<uint32_t>(), ""); + static_assert(constexpr_test<uint64_t>(), ""); + static_assert(constexpr_test<size_t>(), ""); + static_assert(constexpr_test<uintmax_t>(), ""); + static_assert(constexpr_test<uintptr_t>(), ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert(constexpr_test<__uint128_t>(), ""); +#endif + + + runtime_test<unsigned char>(); + runtime_test<unsigned>(); + runtime_test<unsigned short>(); + runtime_test<unsigned long>(); + runtime_test<unsigned long long>(); + + runtime_test<uint8_t>(); + runtime_test<uint16_t>(); + runtime_test<uint32_t>(); + runtime_test<uint64_t>(); + runtime_test<size_t>(); + runtime_test<uintmax_t>(); + runtime_test<uintptr_t>(); + +#ifndef _LIBCPP_HAS_NO_INT128 + runtime_test<__uint128_t>(); + + { + __uint128_t val = 128; + + val <<= 32; + assert( std::countr_one(val-1) == 39); + assert( std::countr_one(val) == 0); + assert( std::countr_one(val+1) == 1); + val <<= 2; + assert( std::countr_one(val-1) == 41); + assert( std::countr_one(val) == 0); + assert( std::countr_one(val+1) == 1); + val <<= 3; + assert( std::countr_one(val-1) == 44); + assert( std::countr_one(val) == 0); + assert( std::countr_one(val+1) == 1); + } +#endif + +} Index: libcxx/test/std/numerics/bit/bitops.count/countl_zero.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/numerics/bit/bitops.count/countl_zero.pass.cpp @@ -0,0 +1,172 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// template <class T> +// constexpr int countl_zero(T x) noexcept; + +// Returns: The number of consecutive 0 bits, starting from the most significant bit. +// [ Note: Returns N if x == 0. ] +// +// Remarks: This function shall not participate in overload resolution unless +// T is an unsigned integer type + +#include <bit> +#include <cstdint> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +class A{}; +enum E1 : unsigned char { rEd }; +enum class E2 : unsigned char { red }; + +template <typename T> +constexpr bool constexpr_test() +{ + const int dig = std::numeric_limits<T>::digits; + return std::countl_zero(T(0)) == dig + && std::countl_zero(T(1)) == dig - 1 + && std::countl_zero(T(2)) == dig - 2 + && std::countl_zero(T(3)) == dig - 2 + && std::countl_zero(T(4)) == dig - 3 + && std::countl_zero(T(5)) == dig - 3 + && std::countl_zero(T(6)) == dig - 3 + && std::countl_zero(T(7)) == dig - 3 + && std::countl_zero(T(8)) == dig - 4 + && std::countl_zero(T(9)) == dig - 4 + && std::countl_zero(std::numeric_limits<T>::max()) == 0 + ; +} + + +template <typename T> +void runtime_test() +{ + ASSERT_SAME_TYPE(int, decltype(std::countl_zero(T(0)))); + ASSERT_NOEXCEPT( std::countl_zero(T(0))); + const int dig = std::numeric_limits<T>::digits; + + assert( std::countl_zero(T(121)) == dig - 7); + assert( std::countl_zero(T(122)) == dig - 7); + assert( std::countl_zero(T(123)) == dig - 7); + assert( std::countl_zero(T(124)) == dig - 7); + assert( std::countl_zero(T(125)) == dig - 7); + assert( std::countl_zero(T(126)) == dig - 7); + assert( std::countl_zero(T(127)) == dig - 7); + assert( std::countl_zero(T(128)) == dig - 8); + assert( std::countl_zero(T(129)) == dig - 8); + assert( std::countl_zero(T(130)) == dig - 8); +} + +int main() +{ + + { + auto lambda = [](auto x) -> decltype(std::countl_zero(x)) {}; + using L = decltype(lambda); + + static_assert( std::is_invocable_v<L, unsigned char>, ""); + static_assert( std::is_invocable_v<L, unsigned int>, ""); + static_assert( std::is_invocable_v<L, unsigned long>, ""); + static_assert( std::is_invocable_v<L, unsigned long long>, ""); + + static_assert( std::is_invocable_v<L, uint8_t>, ""); + static_assert( std::is_invocable_v<L, uint16_t>, ""); + static_assert( std::is_invocable_v<L, uint32_t>, ""); + static_assert( std::is_invocable_v<L, uint64_t>, ""); + static_assert( std::is_invocable_v<L, size_t>, ""); + + static_assert( std::is_invocable_v<L, uintmax_t>, ""); + static_assert( std::is_invocable_v<L, uintptr_t>, ""); + + + static_assert(!std::is_invocable_v<L, int>, ""); + static_assert(!std::is_invocable_v<L, signed int>, ""); + static_assert(!std::is_invocable_v<L, long>, ""); + static_assert(!std::is_invocable_v<L, long long>, ""); + + static_assert(!std::is_invocable_v<L, int8_t>, ""); + static_assert(!std::is_invocable_v<L, int16_t>, ""); + static_assert(!std::is_invocable_v<L, int32_t>, ""); + static_assert(!std::is_invocable_v<L, int64_t>, ""); + static_assert(!std::is_invocable_v<L, ptrdiff_t>, ""); + + static_assert(!std::is_invocable_v<L, bool>, ""); + static_assert(!std::is_invocable_v<L, signed char>, ""); + static_assert(!std::is_invocable_v<L, char16_t>, ""); + static_assert(!std::is_invocable_v<L, char32_t>, ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert( std::is_invocable_v<L, __uint128_t>, ""); + static_assert(!std::is_invocable_v<L, __int128_t>, ""); +#endif + + static_assert(!std::is_invocable_v<L, A>, ""); + static_assert(!std::is_invocable_v<L, E1>, ""); + static_assert(!std::is_invocable_v<L, E2>, ""); + } + + static_assert(constexpr_test<unsigned char>(), ""); + static_assert(constexpr_test<unsigned short>(), ""); + static_assert(constexpr_test<unsigned>(), ""); + static_assert(constexpr_test<unsigned long>(), ""); + static_assert(constexpr_test<unsigned long long>(), ""); + + static_assert(constexpr_test<uint8_t>(), ""); + static_assert(constexpr_test<uint16_t>(), ""); + static_assert(constexpr_test<uint32_t>(), ""); + static_assert(constexpr_test<uint64_t>(), ""); + static_assert(constexpr_test<size_t>(), ""); + static_assert(constexpr_test<uintmax_t>(), ""); + static_assert(constexpr_test<uintptr_t>(), ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert(constexpr_test<__uint128_t>(), ""); +#endif + + + runtime_test<unsigned char>(); + runtime_test<unsigned>(); + runtime_test<unsigned short>(); + runtime_test<unsigned long>(); + runtime_test<unsigned long long>(); + + runtime_test<uint8_t>(); + runtime_test<uint16_t>(); + runtime_test<uint32_t>(); + runtime_test<uint64_t>(); + runtime_test<size_t>(); + runtime_test<uintmax_t>(); + runtime_test<uintptr_t>(); + +#ifndef _LIBCPP_HAS_NO_INT128 + runtime_test<__uint128_t>(); + + { + const int dig = std::numeric_limits<__uint128_t>::digits; + __uint128_t val = 128; + + val <<= 32; + assert( std::countl_zero(val-1) == dig - 39); + assert( std::countl_zero(val) == dig - 40); + assert( std::countl_zero(val+1) == dig - 40); + val <<= 2; + assert( std::countl_zero(val-1) == dig - 41); + assert( std::countl_zero(val) == dig - 42); + assert( std::countl_zero(val+1) == dig - 42); + val <<= 3; + assert( std::countl_zero(val-1) == dig - 44); + assert( std::countl_zero(val) == dig - 45); + assert( std::countl_zero(val+1) == dig - 45); + } +#endif + +} Index: libcxx/test/std/numerics/bit/bitops.count/countl_one.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/numerics/bit/bitops.count/countl_one.pass.cpp @@ -0,0 +1,165 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// template <class T> +// constexpr int countl_one(T x) noexcept; + +// The number of consecutive 1 bits, starting from the most significant bit. +// [ Note: Returns N if x == std::numeric_limits<T>::max(). ] +// +// Remarks: This function shall not participate in overload resolution unless +// T is an unsigned integer type + +#include <bit> +#include <cstdint> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +class A{}; +enum E1 : unsigned char { rEd }; +enum class E2 : unsigned char { red }; + +template <typename T> +constexpr bool constexpr_test() +{ + const int dig = std::numeric_limits<T>::digits; + const T max = std::numeric_limits<T>::max(); + return std::countl_one(max) == dig + && std::countl_one(T(max - 1)) == dig - 1 + && std::countl_one(T(max - 2)) == dig - 2 + && std::countl_one(T(max - 3)) == dig - 2 + && std::countl_one(T(max - 4)) == dig - 3 + && std::countl_one(T(max - 5)) == dig - 3 + && std::countl_one(T(max - 6)) == dig - 3 + && std::countl_one(T(max - 7)) == dig - 3 + && std::countl_one(T(max - 8)) == dig - 4 + && std::countl_one(T(max - 9)) == dig - 4 + ; +} + + +template <typename T> +void runtime_test() +{ + ASSERT_SAME_TYPE(int, decltype(std::countl_one(T(0)))); + ASSERT_NOEXCEPT( std::countl_one(T(0))); + const int dig = std::numeric_limits<T>::digits; + + assert( std::countl_one(T(~121)) == dig - 7); + assert( std::countl_one(T(~122)) == dig - 7); + assert( std::countl_one(T(~123)) == dig - 7); + assert( std::countl_one(T(~124)) == dig - 7); + assert( std::countl_one(T(~125)) == dig - 7); + assert( std::countl_one(T(~126)) == dig - 7); + assert( std::countl_one(T(~127)) == dig - 7); + assert( std::countl_one(T(~128)) == dig - 8); + assert( std::countl_one(T(~129)) == dig - 8); + assert( std::countl_one(T(~130)) == dig - 8); +} + +int main() +{ + { + auto lambda = [](auto x) -> decltype(std::countl_one(x)) {}; + using L = decltype(lambda); + + static_assert( std::is_invocable_v<L, unsigned char>, ""); + static_assert( std::is_invocable_v<L, unsigned int>, ""); + static_assert( std::is_invocable_v<L, unsigned long>, ""); + static_assert( std::is_invocable_v<L, unsigned long long>, ""); + + static_assert( std::is_invocable_v<L, uint8_t>, ""); + static_assert( std::is_invocable_v<L, uint16_t>, ""); + static_assert( std::is_invocable_v<L, uint32_t>, ""); + static_assert( std::is_invocable_v<L, uint64_t>, ""); + static_assert( std::is_invocable_v<L, size_t>, ""); + + static_assert( std::is_invocable_v<L, uintmax_t>, ""); + static_assert( std::is_invocable_v<L, uintptr_t>, ""); + + + static_assert(!std::is_invocable_v<L, int>, ""); + static_assert(!std::is_invocable_v<L, signed int>, ""); + static_assert(!std::is_invocable_v<L, long>, ""); + static_assert(!std::is_invocable_v<L, long long>, ""); + + static_assert(!std::is_invocable_v<L, int8_t>, ""); + static_assert(!std::is_invocable_v<L, int16_t>, ""); + static_assert(!std::is_invocable_v<L, int32_t>, ""); + static_assert(!std::is_invocable_v<L, int64_t>, ""); + static_assert(!std::is_invocable_v<L, ptrdiff_t>, ""); + + static_assert(!std::is_invocable_v<L, bool>, ""); + static_assert(!std::is_invocable_v<L, signed char>, ""); + static_assert(!std::is_invocable_v<L, char16_t>, ""); + static_assert(!std::is_invocable_v<L, char32_t>, ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert( std::is_invocable_v<L, __uint128_t>, ""); + static_assert(!std::is_invocable_v<L, __int128_t>, ""); +#endif + + static_assert(!std::is_invocable_v<L, A>, ""); + static_assert(!std::is_invocable_v<L, E1>, ""); + static_assert(!std::is_invocable_v<L, E2>, ""); + } + + static_assert(constexpr_test<unsigned char>(), ""); + static_assert(constexpr_test<unsigned short>(), ""); + static_assert(constexpr_test<unsigned>(), ""); + static_assert(constexpr_test<unsigned long>(), ""); + static_assert(constexpr_test<unsigned long long>(), ""); + + static_assert(constexpr_test<uint8_t>(), ""); + static_assert(constexpr_test<uint16_t>(), ""); + static_assert(constexpr_test<uint32_t>(), ""); + static_assert(constexpr_test<uint64_t>(), ""); + static_assert(constexpr_test<size_t>(), ""); + static_assert(constexpr_test<uintmax_t>(), ""); + static_assert(constexpr_test<uintptr_t>(), ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert(constexpr_test<__uint128_t>(), ""); +#endif + + + runtime_test<unsigned char>(); + runtime_test<unsigned>(); + runtime_test<unsigned short>(); + runtime_test<unsigned long>(); + runtime_test<unsigned long long>(); + + runtime_test<uint8_t>(); + runtime_test<uint16_t>(); + runtime_test<uint32_t>(); + runtime_test<uint64_t>(); + runtime_test<size_t>(); + runtime_test<uintmax_t>(); + runtime_test<uintptr_t>(); + +#ifndef _LIBCPP_HAS_NO_INT128 + runtime_test<__uint128_t>(); + + { + const int dig = std::numeric_limits<__uint128_t>::digits; + __uint128_t val = 128; + + val <<= 32; + assert( std::countl_one(~val) == dig - 40); + val <<= 2; + assert( std::countl_one(~val) == dig - 42); + val <<= 3; + assert( std::countl_one(~val) == dig - 45); + } +#endif + +} Index: libcxx/test/std/numerics/bit/bit.pow.two/log2p1.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/numerics/bit/bit.pow.two/log2p1.pass.cpp @@ -0,0 +1,177 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// template <class T> +// constexpr T log2p1(T x) noexcept; + +// If x == 0, 0; otherwise one plus the base-2 logarithm of x, with any fractional part discarded. + +// Remarks: This function shall not participate in overload resolution unless +// T is an unsigned integer type + +#include <bit> +#include <cstdint> +#include <cassert> + +#include "test_macros.h" + +class A{}; +enum E1 : unsigned char { rEd }; +enum class E2 : unsigned char { red }; + +template <typename T> +constexpr bool constexpr_test() +{ + return std::log2p1(T(0)) == T(0) + && std::log2p1(T(1)) == T(1) + && std::log2p1(T(2)) == T(2) + && std::log2p1(T(3)) == T(2) + && std::log2p1(T(4)) == T(3) + && std::log2p1(T(5)) == T(3) + && std::log2p1(T(6)) == T(3) + && std::log2p1(T(7)) == T(3) + && std::log2p1(T(8)) == T(4) + && std::log2p1(T(9)) == T(4) + ; +} + + +template <typename T> +void runtime_test() +{ + ASSERT_SAME_TYPE(T, decltype(std::log2p1(T(0)))); + ASSERT_NOEXCEPT( std::log2p1(T(0))); + + assert( std::log2p1(T(0)) == T(0)); + assert( std::log2p1(T(1)) == T(1)); + assert( std::log2p1(T(2)) == T(2)); + assert( std::log2p1(T(3)) == T(2)); + assert( std::log2p1(T(4)) == T(3)); + assert( std::log2p1(T(5)) == T(3)); + assert( std::log2p1(T(6)) == T(3)); + assert( std::log2p1(T(7)) == T(3)); + assert( std::log2p1(T(8)) == T(4)); + assert( std::log2p1(T(9)) == T(4)); + + + assert( std::log2p1(T(121)) == T(7)); + assert( std::log2p1(T(122)) == T(7)); + assert( std::log2p1(T(123)) == T(7)); + assert( std::log2p1(T(124)) == T(7)); + assert( std::log2p1(T(125)) == T(7)); + assert( std::log2p1(T(126)) == T(7)); + assert( std::log2p1(T(127)) == T(7)); + assert( std::log2p1(T(128)) == T(8)); + assert( std::log2p1(T(129)) == T(8)); + assert( std::log2p1(T(130)) == T(8)); +} + +int main() +{ + + { + auto lambda = [](auto x) -> decltype(std::log2p1(x)) {}; + using L = decltype(lambda); + + static_assert( std::is_invocable_v<L, unsigned char>, ""); + static_assert( std::is_invocable_v<L, unsigned int>, ""); + static_assert( std::is_invocable_v<L, unsigned long>, ""); + static_assert( std::is_invocable_v<L, unsigned long long>, ""); + + static_assert( std::is_invocable_v<L, uint8_t>, ""); + static_assert( std::is_invocable_v<L, uint16_t>, ""); + static_assert( std::is_invocable_v<L, uint32_t>, ""); + static_assert( std::is_invocable_v<L, uint64_t>, ""); + static_assert( std::is_invocable_v<L, size_t>, ""); + + static_assert( std::is_invocable_v<L, uintmax_t>, ""); + static_assert( std::is_invocable_v<L, uintptr_t>, ""); + + + static_assert(!std::is_invocable_v<L, int>, ""); + static_assert(!std::is_invocable_v<L, signed int>, ""); + static_assert(!std::is_invocable_v<L, long>, ""); + static_assert(!std::is_invocable_v<L, long long>, ""); + + static_assert(!std::is_invocable_v<L, int8_t>, ""); + static_assert(!std::is_invocable_v<L, int16_t>, ""); + static_assert(!std::is_invocable_v<L, int32_t>, ""); + static_assert(!std::is_invocable_v<L, int64_t>, ""); + static_assert(!std::is_invocable_v<L, ptrdiff_t>, ""); + + static_assert(!std::is_invocable_v<L, bool>, ""); + static_assert(!std::is_invocable_v<L, signed char>, ""); + static_assert(!std::is_invocable_v<L, char16_t>, ""); + static_assert(!std::is_invocable_v<L, char32_t>, ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert( std::is_invocable_v<L, __uint128_t>, ""); + static_assert(!std::is_invocable_v<L, __int128_t>, ""); +#endif + + static_assert(!std::is_invocable_v<L, A>, ""); + static_assert(!std::is_invocable_v<L, E1>, ""); + static_assert(!std::is_invocable_v<L, E2>, ""); + } + + static_assert(constexpr_test<unsigned char>(), ""); + static_assert(constexpr_test<unsigned short>(), ""); + static_assert(constexpr_test<unsigned>(), ""); + static_assert(constexpr_test<unsigned long>(), ""); + static_assert(constexpr_test<unsigned long long>(), ""); + + static_assert(constexpr_test<uint8_t>(), ""); + static_assert(constexpr_test<uint16_t>(), ""); + static_assert(constexpr_test<uint32_t>(), ""); + static_assert(constexpr_test<uint64_t>(), ""); + static_assert(constexpr_test<size_t>(), ""); + static_assert(constexpr_test<uintmax_t>(), ""); + static_assert(constexpr_test<uintptr_t>(), ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert(constexpr_test<__uint128_t>(), ""); +#endif + + + runtime_test<unsigned char>(); + runtime_test<unsigned>(); + runtime_test<unsigned short>(); + runtime_test<unsigned long>(); + runtime_test<unsigned long long>(); + + runtime_test<uint8_t>(); + runtime_test<uint16_t>(); + runtime_test<uint32_t>(); + runtime_test<uint64_t>(); + runtime_test<size_t>(); + runtime_test<uintmax_t>(); + runtime_test<uintptr_t>(); + +#ifndef _LIBCPP_HAS_NO_INT128 + runtime_test<__uint128_t>(); + + { + __uint128_t val = 128; + val <<= 32; + assert( std::log2p1(val-1) == 39); + assert( std::log2p1(val) == 40); + assert( std::log2p1(val+1) == 40); + val <<= 2; + assert( std::log2p1(val-1) == 41); + assert( std::log2p1(val) == 42); + assert( std::log2p1(val+1) == 42); + val <<= 3; + assert( std::log2p1(val-1) == 44); + assert( std::log2p1(val) == 45); + assert( std::log2p1(val+1) == 45); + } +#endif + +} Index: libcxx/test/std/numerics/bit/bit.pow.two/ispow2.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/numerics/bit/bit.pow.two/ispow2.pass.cpp @@ -0,0 +1,162 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// template <class T> +// constexpr bool ispow2(T x) noexcept; + +// Remarks: This function shall not participate in overload resolution unless +// T is an unsigned integer type + +#include <bit> +#include <cstdint> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +class A{}; +enum E1 : unsigned char { rEd }; +enum class E2 : unsigned char { red }; + +template <typename T> +constexpr bool constexpr_test() +{ + return std::ispow2(T(1)) + && std::ispow2(T(2)) + && !std::ispow2(T(3)) + && std::ispow2(T(4)) + && !std::ispow2(T(5)) + && !std::ispow2(T(6)) + && !std::ispow2(T(7)) + && std::ispow2(T(8)) + && !std::ispow2(T(9)) + ; +} + + +template <typename T> +void runtime_test() +{ + ASSERT_SAME_TYPE(bool, decltype(std::ispow2(T(0)))); + ASSERT_NOEXCEPT( std::ispow2(T(0))); + + assert(!std::ispow2(T(121))); + assert(!std::ispow2(T(122))); + assert(!std::ispow2(T(123))); + assert(!std::ispow2(T(124))); + assert(!std::ispow2(T(125))); + assert(!std::ispow2(T(126))); + assert(!std::ispow2(T(127))); + assert( std::ispow2(T(128))); + assert(!std::ispow2(T(129))); + assert(!std::ispow2(T(130))); +} + +int main() +{ + + { + auto lambda = [](auto x) -> decltype(std::ispow2(x)) {}; + using L = decltype(lambda); + + static_assert( std::is_invocable_v<L, unsigned char>, ""); + static_assert( std::is_invocable_v<L, unsigned int>, ""); + static_assert( std::is_invocable_v<L, unsigned long>, ""); + static_assert( std::is_invocable_v<L, unsigned long long>, ""); + + static_assert( std::is_invocable_v<L, uint8_t>, ""); + static_assert( std::is_invocable_v<L, uint16_t>, ""); + static_assert( std::is_invocable_v<L, uint32_t>, ""); + static_assert( std::is_invocable_v<L, uint64_t>, ""); + static_assert( std::is_invocable_v<L, size_t>, ""); + + static_assert( std::is_invocable_v<L, uintmax_t>, ""); + static_assert( std::is_invocable_v<L, uintptr_t>, ""); + + + static_assert(!std::is_invocable_v<L, int>, ""); + static_assert(!std::is_invocable_v<L, signed int>, ""); + static_assert(!std::is_invocable_v<L, long>, ""); + static_assert(!std::is_invocable_v<L, long long>, ""); + + static_assert(!std::is_invocable_v<L, int8_t>, ""); + static_assert(!std::is_invocable_v<L, int16_t>, ""); + static_assert(!std::is_invocable_v<L, int32_t>, ""); + static_assert(!std::is_invocable_v<L, int64_t>, ""); + static_assert(!std::is_invocable_v<L, ptrdiff_t>, ""); + + static_assert(!std::is_invocable_v<L, bool>, ""); + static_assert(!std::is_invocable_v<L, signed char>, ""); + static_assert(!std::is_invocable_v<L, char16_t>, ""); + static_assert(!std::is_invocable_v<L, char32_t>, ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert( std::is_invocable_v<L, __uint128_t>, ""); + static_assert(!std::is_invocable_v<L, __int128_t>, ""); +#endif + + static_assert(!std::is_invocable_v<L, A>, ""); + static_assert(!std::is_invocable_v<L, E1>, ""); + static_assert(!std::is_invocable_v<L, E2>, ""); + } + + static_assert(constexpr_test<unsigned char>(), ""); + static_assert(constexpr_test<unsigned short>(), ""); + static_assert(constexpr_test<unsigned>(), ""); + static_assert(constexpr_test<unsigned long>(), ""); + static_assert(constexpr_test<unsigned long long>(), ""); + + static_assert(constexpr_test<uint8_t>(), ""); + static_assert(constexpr_test<uint16_t>(), ""); + static_assert(constexpr_test<uint32_t>(), ""); + static_assert(constexpr_test<uint64_t>(), ""); + static_assert(constexpr_test<size_t>(), ""); + static_assert(constexpr_test<uintmax_t>(), ""); + static_assert(constexpr_test<uintptr_t>(), ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert(constexpr_test<__uint128_t>(), ""); +#endif + + runtime_test<unsigned char>(); + runtime_test<unsigned>(); + runtime_test<unsigned short>(); + runtime_test<unsigned long>(); + runtime_test<unsigned long long>(); + + runtime_test<uint8_t>(); + runtime_test<uint16_t>(); + runtime_test<uint32_t>(); + runtime_test<uint64_t>(); + runtime_test<size_t>(); + runtime_test<uintmax_t>(); + runtime_test<uintptr_t>(); + +#ifndef _LIBCPP_HAS_NO_INT128 + runtime_test<__uint128_t>(); + + { + __uint128_t val = 128; + val <<= 32; + assert(!std::ispow2(val-1)); + assert( std::ispow2(val)); + assert(!std::ispow2(val+1)); + val <<= 2; + assert(!std::ispow2(val-1)); + assert( std::ispow2(val)); + assert(!std::ispow2(val+1)); + val <<= 3; + assert(!std::ispow2(val-1)); + assert( std::ispow2(val)); + assert(!std::ispow2(val+1)); + } +#endif + +} Index: libcxx/test/std/numerics/bit/bit.pow.two/floor2.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/numerics/bit/bit.pow.two/floor2.pass.cpp @@ -0,0 +1,164 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// template <class T> +// constexpr T floor2(T x) noexcept; + +// Returns: If x == 0, 0; otherwise the maximal value y such that floor2(y) is true and y <= x. +// Remarks: This function shall not participate in overload resolution unless +// T is an unsigned integer type + +#include <bit> +#include <cstdint> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +class A{}; +enum E1 : unsigned char { rEd }; +enum class E2 : unsigned char { red }; + +template <typename T> +constexpr bool constexpr_test() +{ + return std::floor2(T(0)) == T(0) + && std::floor2(T(1)) == T(1) + && std::floor2(T(2)) == T(2) + && std::floor2(T(3)) == T(2) + && std::floor2(T(4)) == T(4) + && std::floor2(T(5)) == T(4) + && std::floor2(T(6)) == T(4) + && std::floor2(T(7)) == T(4) + && std::floor2(T(8)) == T(8) + && std::floor2(T(9)) == T(8) + ; +} + + +template <typename T> +void runtime_test() +{ + ASSERT_SAME_TYPE(T, decltype(std::floor2(T(0)))); + ASSERT_NOEXCEPT( std::floor2(T(0))); + + assert( std::floor2(T(121)) == T(64)); + assert( std::floor2(T(122)) == T(64)); + assert( std::floor2(T(123)) == T(64)); + assert( std::floor2(T(124)) == T(64)); + assert( std::floor2(T(125)) == T(64)); + assert( std::floor2(T(126)) == T(64)); + assert( std::floor2(T(127)) == T(64)); + assert( std::floor2(T(128)) == T(128)); + assert( std::floor2(T(129)) == T(128)); + assert( std::floor2(T(130)) == T(128)); +} + +int main() +{ + + { + auto lambda = [](auto x) -> decltype(std::floor2(x)) {}; + using L = decltype(lambda); + + static_assert( std::is_invocable_v<L, unsigned char>, ""); + static_assert( std::is_invocable_v<L, unsigned int>, ""); + static_assert( std::is_invocable_v<L, unsigned long>, ""); + static_assert( std::is_invocable_v<L, unsigned long long>, ""); + + static_assert( std::is_invocable_v<L, uint8_t>, ""); + static_assert( std::is_invocable_v<L, uint16_t>, ""); + static_assert( std::is_invocable_v<L, uint32_t>, ""); + static_assert( std::is_invocable_v<L, uint64_t>, ""); + static_assert( std::is_invocable_v<L, size_t>, ""); + + static_assert( std::is_invocable_v<L, uintmax_t>, ""); + static_assert( std::is_invocable_v<L, uintptr_t>, ""); + + + static_assert(!std::is_invocable_v<L, int>, ""); + static_assert(!std::is_invocable_v<L, signed int>, ""); + static_assert(!std::is_invocable_v<L, long>, ""); + static_assert(!std::is_invocable_v<L, long long>, ""); + + static_assert(!std::is_invocable_v<L, int8_t>, ""); + static_assert(!std::is_invocable_v<L, int16_t>, ""); + static_assert(!std::is_invocable_v<L, int32_t>, ""); + static_assert(!std::is_invocable_v<L, int64_t>, ""); + static_assert(!std::is_invocable_v<L, ptrdiff_t>, ""); + + static_assert(!std::is_invocable_v<L, bool>, ""); + static_assert(!std::is_invocable_v<L, signed char>, ""); + static_assert(!std::is_invocable_v<L, char16_t>, ""); + static_assert(!std::is_invocable_v<L, char32_t>, ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert( std::is_invocable_v<L, __uint128_t>, ""); + static_assert(!std::is_invocable_v<L, __int128_t>, ""); +#endif + + static_assert(!std::is_invocable_v<L, A>, ""); + static_assert(!std::is_invocable_v<L, E1>, ""); + static_assert(!std::is_invocable_v<L, E2>, ""); + } + + static_assert(constexpr_test<unsigned char>(), ""); + static_assert(constexpr_test<unsigned short>(), ""); + static_assert(constexpr_test<unsigned>(), ""); + static_assert(constexpr_test<unsigned long>(), ""); + static_assert(constexpr_test<unsigned long long>(), ""); + + static_assert(constexpr_test<uint8_t>(), ""); + static_assert(constexpr_test<uint16_t>(), ""); + static_assert(constexpr_test<uint32_t>(), ""); + static_assert(constexpr_test<uint64_t>(), ""); + static_assert(constexpr_test<size_t>(), ""); + static_assert(constexpr_test<uintmax_t>(), ""); + static_assert(constexpr_test<uintptr_t>(), ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert(constexpr_test<__uint128_t>(), ""); +#endif + + runtime_test<unsigned char>(); + runtime_test<unsigned>(); + runtime_test<unsigned short>(); + runtime_test<unsigned long>(); + runtime_test<unsigned long long>(); + + runtime_test<uint8_t>(); + runtime_test<uint16_t>(); + runtime_test<uint32_t>(); + runtime_test<uint64_t>(); + runtime_test<size_t>(); + runtime_test<uintmax_t>(); + runtime_test<uintptr_t>(); + +#ifndef _LIBCPP_HAS_NO_INT128 + runtime_test<__uint128_t>(); + + { + __uint128_t val = 128; + val <<= 32; + assert( std::floor2(val-1) == val/2); + assert( std::floor2(val) == val); + assert( std::floor2(val+1) == val); + val <<= 2; + assert( std::floor2(val-1) == val/2); + assert( std::floor2(val) == val); + assert( std::floor2(val+1) == val); + val <<= 3; + assert( std::floor2(val-1) == val/2); + assert( std::floor2(val) == val); + assert( std::floor2(val+1) == val); + } +#endif + +} Index: libcxx/test/std/numerics/bit/bit.pow.two/ceil2.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/numerics/bit/bit.pow.two/ceil2.pass.cpp @@ -0,0 +1,148 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// template <class T> +// constexpr T ceil2(T x) noexcept; + +// Returns: The minimal value y such that ispow2(y) is true and y >= x; +// if y is not representable as a value of type T, the result is an unspecified value. +// Remarks: This function shall not participate in overload resolution unless +// T is an unsigned integer type + +#include <bit> +#include <cstdint> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +class A{}; +enum E1 : unsigned char { rEd }; +enum class E2 : unsigned char { red }; + +template <typename T> +constexpr bool constexpr_test() +{ + return std::ceil2(T(0)) == T(1) + && std::ceil2(T(1)) == T(1) + && std::ceil2(T(2)) == T(2) + && std::ceil2(T(3)) == T(4) + && std::ceil2(T(4)) == T(4) + && std::ceil2(T(5)) == T(8) + && std::ceil2(T(6)) == T(8) + && std::ceil2(T(7)) == T(8) + && std::ceil2(T(8)) == T(8) + && std::ceil2(T(9)) == T(16) + ; +} + + +template <typename T> +void runtime_test() +{ + ASSERT_SAME_TYPE(T, decltype(std::ceil2(T(0)))); + LIBCPP_ASSERT_NOEXCEPT( std::ceil2(T(0))); + + assert( std::ceil2(T(60)) == T( 64)); + assert( std::ceil2(T(61)) == T( 64)); + assert( std::ceil2(T(62)) == T( 64)); + assert( std::ceil2(T(63)) == T( 64)); + assert( std::ceil2(T(64)) == T( 64)); + assert( std::ceil2(T(65)) == T(128)); + assert( std::ceil2(T(66)) == T(128)); + assert( std::ceil2(T(67)) == T(128)); + assert( std::ceil2(T(68)) == T(128)); + assert( std::ceil2(T(69)) == T(128)); +} + +int main() +{ + + { + auto lambda = [](auto x) -> decltype(std::ceil2(x)) {}; + using L = decltype(lambda); + + static_assert( std::is_invocable_v<L, unsigned char>, ""); + static_assert( std::is_invocable_v<L, unsigned int>, ""); + static_assert( std::is_invocable_v<L, unsigned long>, ""); + static_assert( std::is_invocable_v<L, unsigned long long>, ""); + + static_assert( std::is_invocable_v<L, uint8_t>, ""); + static_assert( std::is_invocable_v<L, uint16_t>, ""); + static_assert( std::is_invocable_v<L, uint32_t>, ""); + static_assert( std::is_invocable_v<L, uint64_t>, ""); + static_assert( std::is_invocable_v<L, size_t>, ""); + + static_assert( std::is_invocable_v<L, uintmax_t>, ""); + static_assert( std::is_invocable_v<L, uintptr_t>, ""); + + + static_assert(!std::is_invocable_v<L, int>, ""); + static_assert(!std::is_invocable_v<L, signed int>, ""); + static_assert(!std::is_invocable_v<L, long>, ""); + static_assert(!std::is_invocable_v<L, long long>, ""); + + static_assert(!std::is_invocable_v<L, int8_t>, ""); + static_assert(!std::is_invocable_v<L, int16_t>, ""); + static_assert(!std::is_invocable_v<L, int32_t>, ""); + static_assert(!std::is_invocable_v<L, int64_t>, ""); + static_assert(!std::is_invocable_v<L, ptrdiff_t>, ""); + + static_assert(!std::is_invocable_v<L, bool>, ""); + static_assert(!std::is_invocable_v<L, signed char>, ""); + static_assert(!std::is_invocable_v<L, char16_t>, ""); + static_assert(!std::is_invocable_v<L, char32_t>, ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert( std::is_invocable_v<L, __uint128_t>, ""); + static_assert(!std::is_invocable_v<L, __int128_t>, ""); +#endif + + static_assert(!std::is_invocable_v<L, A>, ""); + static_assert(!std::is_invocable_v<L, E1>, ""); + static_assert(!std::is_invocable_v<L, E2>, ""); + } + + static_assert(constexpr_test<unsigned char>(), ""); + static_assert(constexpr_test<unsigned short>(), ""); + static_assert(constexpr_test<unsigned>(), ""); + static_assert(constexpr_test<unsigned long>(), ""); + static_assert(constexpr_test<unsigned long long>(), ""); + + static_assert(constexpr_test<uint8_t>(), ""); + static_assert(constexpr_test<uint16_t>(), ""); + static_assert(constexpr_test<uint32_t>(), ""); + static_assert(constexpr_test<uint64_t>(), ""); + static_assert(constexpr_test<size_t>(), ""); + static_assert(constexpr_test<uintmax_t>(), ""); + static_assert(constexpr_test<uintptr_t>(), ""); + +#ifndef _LIBCPP_HAS_NO_INT128 + static_assert(constexpr_test<__uint128_t>(), ""); +#endif + + runtime_test<unsigned char>(); + runtime_test<unsigned>(); + runtime_test<unsigned short>(); + runtime_test<unsigned long>(); + runtime_test<unsigned long long>(); + + runtime_test<uint8_t>(); + runtime_test<uint16_t>(); + runtime_test<uint32_t>(); + runtime_test<uint64_t>(); + runtime_test<size_t>(); + runtime_test<uintmax_t>(); + runtime_test<uintptr_t>(); + +#ifndef _LIBCPP_HAS_NO_INT128 + runtime_test<__uint128_t>(); +#endif +} Index: libcxx/test/std/numerics/bit/bit.pow.two/ceil2.fail.cpp =================================================================== --- /dev/null +++ libcxx/test/std/numerics/bit/bit.pow.two/ceil2.fail.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// template <class T> +// constexpr T ceil2(T x) noexcept; + +// Remarks: This function shall not participate in overload resolution unless +// T is an unsigned integer type + +#include <bit> +#include <cstdint> +#include <limits> +#include <cassert> + +#include "test_macros.h" + +class A{}; +enum E1 : unsigned char { rEd }; +enum class E2 : unsigned char { red }; + +template <typename T> +constexpr bool toobig() +{ + return 0 == std::ceil2(std::numeric_limits<T>::max()); +} + +int main() +{ +// Make sure we generate a compile-time error for UB + static_assert(toobig<unsigned char>(), ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(toobig<unsigned short>(), ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(toobig<unsigned>(), ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(toobig<unsigned long>(), ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(toobig<unsigned long long>(), ""); // expected-error {{static_assert expression is not an integral constant expression}} + + static_assert(toobig<uint8_t>(), ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(toobig<uint16_t>(), ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(toobig<uint32_t>(), ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(toobig<uint64_t>(), ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(toobig<size_t>(), ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(toobig<uintmax_t>(), ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(toobig<uintptr_t>(), ""); // expected-error {{static_assert expression is not an integral constant expression}} +} Index: libcxx/include/bit =================================================================== --- libcxx/include/bit +++ libcxx/include/bit @@ -15,12 +15,42 @@ namespace std { + template <class T> + constexpr bool ispow2(T x) noexcept; // C++20 + template <class T> + constexpr T ceil2(T x); // C++20 + template <class T> + constexpr T floor2(T x) noexcept; // C++20 + template <class T> + constexpr T log2p1(T x) noexcept; // C++20 + + // 23.20.2, rotating + template<class T> + constexpr T rotl(T x, unsigned int s) noexcept; // C++20 + template<class T> + constexpr T rotr(T x, unsigned int s) noexcept; // C++20 + + // 23.20.3, counting + template<class T> + constexpr int countl_zero(T x) noexcept; // C++20 + template<class T> + constexpr int countl_one(T x) noexcept; // C++20 + template<class T> + constexpr int countr_zero(T x) noexcept; // C++20 + template<class T> + constexpr int countr_one(T x) noexcept; // C++20 + template<class T> + constexpr int popcount(T x) noexcept; // C++20 + } // namespace std */ #include <__config> +#include <limits> +#include <type_traits> #include <version> +#include <__debug> #if defined(__IBMCPP__) #include "support/ibm/support.h" @@ -33,38 +63,41 @@ #pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #ifndef _LIBCPP_COMPILER_MSVC -inline _LIBCPP_INLINE_VISIBILITY -int __ctz(unsigned __x) { return __builtin_ctz(__x); } +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __ctz(unsigned __x) _NOEXCEPT { return __builtin_ctz(__x); } -inline _LIBCPP_INLINE_VISIBILITY -int __ctz(unsigned long __x) { return __builtin_ctzl(__x); } +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __ctz(unsigned long __x) _NOEXCEPT { return __builtin_ctzl(__x); } -inline _LIBCPP_INLINE_VISIBILITY -int __ctz(unsigned long long __x) { return __builtin_ctzll(__x); } +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); } -inline _LIBCPP_INLINE_VISIBILITY -int __clz(unsigned __x) { return __builtin_clz(__x); } +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __clz(unsigned __x) _NOEXCEPT { return __builtin_clz(__x); } -inline _LIBCPP_INLINE_VISIBILITY -int __clz(unsigned long __x) { return __builtin_clzl(__x); } +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x); } -inline _LIBCPP_INLINE_VISIBILITY -int __clz(unsigned long long __x) { return __builtin_clzll(__x); } +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); } -inline _LIBCPP_INLINE_VISIBILITY -int __popcount(unsigned __x) { return __builtin_popcount(__x); } +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __popcount(unsigned __x) _NOEXCEPT { return __builtin_popcount(__x); } -inline _LIBCPP_INLINE_VISIBILITY -int __popcount(unsigned long __x) { return __builtin_popcountl(__x); } +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __popcount(unsigned long __x) _NOEXCEPT { return __builtin_popcountl(__x); } -inline _LIBCPP_INLINE_VISIBILITY -int __popcount(unsigned long long __x) { return __builtin_popcountll(__x); } +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popcountll(__x); } #else // _LIBCPP_COMPILER_MSVC @@ -152,6 +185,209 @@ #endif // _LIBCPP_COMPILER_MSVC +#if _LIBCPP_STD_VER > 17 + +template <class _Tp> +using __bitop_unsigned_integer _LIBCPP_NODEBUG_TYPE = integral_constant<bool, + is_integral_v<_Tp> && + is_unsigned_v<_Tp> && + _IsNotSame<remove_cv_t<_Tp>, bool>::value && + _IsNotSame<remove_cv_t<_Tp>, signed char>::value && + _IsNotSame<remove_cv_t<_Tp>, wchar_t>::value && + _IsNotSame<remove_cv_t<_Tp>, char16_t>::value && + _IsNotSame<remove_cv_t<_Tp>, char32_t>::value + >; + + +// rotl +template<class _Tp> +inline _LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp> +rotl(_Tp __t, unsigned int __cnt) noexcept +{ + const unsigned int __dig = numeric_limits<_Tp>::digits; + return (__cnt % __dig) == 0 + ? __t + : (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig))); +} + + +// rotr +template<class _Tp> +inline _LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp> +rotr(_Tp __t, unsigned int __cnt) noexcept +{ + const unsigned int __dig = numeric_limits<_Tp>::digits; + if ((__cnt % __dig) == 0) + return __t; + return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig))); +} + + +// countl_zero +template<class _Tp> +inline _LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t<__bitop_unsigned_integer<_Tp>::value, int> +countl_zero(_Tp __t) noexcept +{ + if (__t == 0) + return numeric_limits<_Tp>::digits; + + if constexpr (sizeof(_Tp) <= sizeof(unsigned int)) + return __clz(static_cast<unsigned int>(__t)) + - (numeric_limits<unsigned int>::digits - numeric_limits<_Tp>::digits); + else if constexpr (sizeof(_Tp) <= sizeof(unsigned long)) + return __clz(static_cast<unsigned long>(__t)) + - (numeric_limits<unsigned long>::digits - numeric_limits<_Tp>::digits); + else if constexpr (sizeof(_Tp) <= sizeof(unsigned long long)) + return __clz(static_cast<unsigned long long>(__t)) + - (numeric_limits<unsigned long long>::digits - numeric_limits<_Tp>::digits); + else + { + int __ret = 0; + int __iter = 0; + const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits; + while (true) { + __t = rotr(__t, __ulldigits); + if ((__iter = countl_zero(static_cast<unsigned long long>(__t))) != __ulldigits) + break; + __ret += __iter; + } + return __ret + __iter; + } +} + + +// countl_one +template<class _Tp> +inline _LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t<__bitop_unsigned_integer<_Tp>::value, int> +countl_one(_Tp __t) noexcept +{ + return __t != numeric_limits<_Tp>::max() + ? countl_zero(static_cast<_Tp>(~__t)) + : numeric_limits<_Tp>::digits; +} + + +// countr_zero +template<class _Tp> +inline _LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t<__bitop_unsigned_integer<_Tp>::value, int> +countr_zero(_Tp __t) noexcept +{ + if (__t == 0) + return numeric_limits<_Tp>::digits; + + if constexpr (sizeof(_Tp) <= sizeof(unsigned int)) + return __ctz(static_cast<unsigned int>(__t)); + else if constexpr (sizeof(_Tp) <= sizeof(unsigned long)) + return __ctz(static_cast<unsigned long>(__t)); + else if constexpr (sizeof(_Tp) <= sizeof(unsigned long long)) + return __ctz(static_cast<unsigned long long>(__t)); + else + { + int __ret = 0; + int __iter = 0; + const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits; + while ((__iter = countr_zero(static_cast<unsigned long long>(__t))) == __ulldigits) + { + __ret += __iter; + __t >>= __ulldigits; + } + return __ret + __iter; + } +} + + +// countr_one +template<class _Tp> +inline _LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t<__bitop_unsigned_integer<_Tp>::value, int> +countr_one(_Tp __t) noexcept +{ + return __t != numeric_limits<_Tp>::max() + ? countr_zero(static_cast<_Tp>(~__t)) + : numeric_limits<_Tp>::digits; +} + + +// popcount +template<class _Tp> +inline _LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t<__bitop_unsigned_integer<_Tp>::value, int> +popcount(_Tp __t) noexcept +{ + if constexpr (sizeof(_Tp) <= sizeof(unsigned int)) + return __popcount(static_cast<unsigned int>(__t)); + else if constexpr (sizeof(_Tp) <= sizeof(unsigned long)) + return __popcount(static_cast<unsigned long>(__t)); + else if constexpr (sizeof(_Tp) <= sizeof(unsigned long long)) + return __popcount(static_cast<unsigned long long>(__t)); + else + { + int __ret = 0; + while (__t != 0) + { + __ret += __popcount(static_cast<unsigned long long>(__t)); + __t >>= numeric_limits<unsigned long long>::digits; + } + return __ret; + } +} + + +// integral log base 2 +template<class _Tp> +inline constexpr +unsigned __bit_log2(_Tp __t) noexcept +{ return std::numeric_limits<_Tp>::digits - 1 - countl_zero(__t); } + + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t<__bitop_unsigned_integer<_Tp>::value, bool> +ispow2(_Tp __t) noexcept { return popcount(__t) == 1; } + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp> +floor2(_Tp __t) noexcept { return __t == 0 ? 0 : _Tp{1} << __bit_log2(__t); } + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp> +ceil2(_Tp __t) noexcept +{ + if (__t < 2) return 1; + const unsigned __n = numeric_limits<_Tp>::digits - countl_zero((_Tp)(__t - 1u)); + +#ifndef _LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED + if (!__builtin_is_constant_evaluated ()) + _LIBCPP_DEBUG_ASSERT( __n != numeric_limits<_Tp>::digits, "Bad input to ceil2" ); +#endif + + if constexpr (sizeof(_Tp) >= sizeof(unsigned)) + return _Tp{1} << __n; + else + { + const unsigned __extra = numeric_limits<unsigned>::digits - numeric_limits<_Tp>::digits; + const unsigned __retVal = 1u << (__n + __extra); + return (_Tp) (__retVal >> __extra); + } +} + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp> +log2p1(_Tp __t) noexcept +{ return __t == 0 ? 0 : __bit_log2(__t) + 1; } + +#endif // _LIBCPP_STD_VER > 17 + _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP_BIT
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits