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 rotl(T x, unsigned int s) noexcept; 13a5c3485aSMarshall Clow 14e130fbe2SArthur O'Dwyer // Constraints: T is an unsigned integer type 15a5c3485aSMarshall Clow 16a5c3485aSMarshall Clow #include <bit> 17e130fbe2SArthur O'Dwyer #include <cassert> 18*d6832a61SLouis Dionne #include <cstddef> 19a5c3485aSMarshall Clow #include <cstdint> 2086aac87fSNikolas Klauser #include <limits> 21a5c3485aSMarshall Clow #include <type_traits> 22a5c3485aSMarshall Clow 23a5c3485aSMarshall Clow #include "test_macros.h" 24a5c3485aSMarshall Clow 25e130fbe2SArthur O'Dwyer struct A {}; 26a5c3485aSMarshall Clow enum E1 : unsigned char { rEd }; 27a5c3485aSMarshall Clow enum class E2 : unsigned char { red }; 28a5c3485aSMarshall Clow 29e130fbe2SArthur O'Dwyer template <class T> 30e130fbe2SArthur O'Dwyer constexpr bool test() 31a5c3485aSMarshall Clow { 32e130fbe2SArthur O'Dwyer ASSERT_SAME_TYPE(decltype(std::rotl(T(), 0)), T); 33e130fbe2SArthur O'Dwyer ASSERT_NOEXCEPT(std::rotl(T(), 0)); 34e130fbe2SArthur O'Dwyer T max = std::numeric_limits<T>::max(); 3545500fa0SDaniil Kalinin T highbit = std::rotr(T(1), 1); 36a5c3485aSMarshall Clow 37e130fbe2SArthur O'Dwyer assert(std::rotl(T(max - 1), 0) == T(max - 1)); 38e130fbe2SArthur O'Dwyer assert(std::rotl(T(max - 1), 1) == T(max - 2)); 39e130fbe2SArthur O'Dwyer assert(std::rotl(T(max - 1), 2) == T(max - 4)); 40e130fbe2SArthur O'Dwyer assert(std::rotl(T(max - 1), 3) == T(max - 8)); 41e130fbe2SArthur O'Dwyer assert(std::rotl(T(max - 1), 4) == T(max - 16)); 42e130fbe2SArthur O'Dwyer assert(std::rotl(T(max - 1), 5) == T(max - 32)); 43e130fbe2SArthur O'Dwyer assert(std::rotl(T(max - 1), 6) == T(max - 64)); 44e130fbe2SArthur O'Dwyer assert(std::rotl(T(max - 1), 7) == T(max - 128)); 4579caa066SMark de Wever assert(std::rotl(T(max - 1), std::numeric_limits<int>::max()) == 4679caa066SMark de Wever std::rotl(T(max - 1), std::numeric_limits<int>::max() % std::numeric_limits<T>::digits)); 47a5c3485aSMarshall Clow 4845500fa0SDaniil Kalinin assert(std::rotl(T(max - 1), -1) == T(max - highbit)); 4945500fa0SDaniil Kalinin assert(std::rotl(T(max - 1), -2) == T(max - (highbit >> 1))); 5045500fa0SDaniil Kalinin assert(std::rotl(T(max - 1), -3) == T(max - (highbit >> 2))); 5145500fa0SDaniil Kalinin assert(std::rotl(T(max - 1), -4) == T(max - (highbit >> 3))); 5245500fa0SDaniil Kalinin assert(std::rotl(T(max - 1), -5) == T(max - (highbit >> 4))); 5345500fa0SDaniil Kalinin assert(std::rotl(T(max - 1), -6) == T(max - (highbit >> 5))); 5445500fa0SDaniil Kalinin assert(std::rotl(T(max - 1), -7) == T(max - (highbit >> 6))); 5579caa066SMark de Wever assert(std::rotl(T(max - 1), std::numeric_limits<int>::min()) == 5679caa066SMark de Wever std::rotl(T(max - 1), std::numeric_limits<int>::min() % std::numeric_limits<T>::digits)); 5745500fa0SDaniil Kalinin 58e130fbe2SArthur O'Dwyer assert(std::rotl(T(1), 0) == T(1)); 59e130fbe2SArthur O'Dwyer assert(std::rotl(T(1), 1) == T(2)); 60e130fbe2SArthur O'Dwyer assert(std::rotl(T(1), 2) == T(4)); 61e130fbe2SArthur O'Dwyer assert(std::rotl(T(1), 3) == T(8)); 62e130fbe2SArthur O'Dwyer assert(std::rotl(T(1), 4) == T(16)); 63e130fbe2SArthur O'Dwyer assert(std::rotl(T(1), 5) == T(32)); 64e130fbe2SArthur O'Dwyer assert(std::rotl(T(1), 6) == T(64)); 65e130fbe2SArthur O'Dwyer assert(std::rotl(T(1), 7) == T(128)); 66a5c3485aSMarshall Clow 6745500fa0SDaniil Kalinin assert(std::rotl(T(128), -1) == T(64)); 6845500fa0SDaniil Kalinin assert(std::rotl(T(128), -2) == T(32)); 6945500fa0SDaniil Kalinin assert(std::rotl(T(128), -3) == T(16)); 7045500fa0SDaniil Kalinin assert(std::rotl(T(128), -4) == T(8)); 7145500fa0SDaniil Kalinin assert(std::rotl(T(128), -5) == T(4)); 7245500fa0SDaniil Kalinin assert(std::rotl(T(128), -6) == T(2)); 7345500fa0SDaniil Kalinin assert(std::rotl(T(128), -7) == T(1)); 7445500fa0SDaniil Kalinin 758f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 76e130fbe2SArthur O'Dwyer if constexpr (std::is_same_v<T, __uint128_t>) { 77e130fbe2SArthur O'Dwyer T val = (T(1) << 63) | (T(1) << 64); 78a5c3485aSMarshall Clow assert(std::rotl(val, 0) == val); 79e130fbe2SArthur O'Dwyer assert(std::rotl(val, 128) == val); 80e130fbe2SArthur O'Dwyer assert(std::rotl(val, 256) == val); 81e130fbe2SArthur O'Dwyer assert(std::rotl(val, 1) == val << 1); 82e130fbe2SArthur O'Dwyer assert(std::rotl(val, 127) == val >> 1); 83e130fbe2SArthur O'Dwyer assert(std::rotl(T(3), 127) == ((T(1) << 127) | T(1))); 8445500fa0SDaniil Kalinin 8545500fa0SDaniil Kalinin assert(std::rotl(val, -128) == val); 8645500fa0SDaniil Kalinin assert(std::rotl(val, -256) == val); 8745500fa0SDaniil Kalinin assert(std::rotl(val, -1) == val >> 1); 8845500fa0SDaniil Kalinin assert(std::rotl(val, -127) == val << 1); 8945500fa0SDaniil Kalinin assert(std::rotl(T(3), -1) == ((T(1) << 127) | T(1))); 90e130fbe2SArthur O'Dwyer } 91e130fbe2SArthur O'Dwyer #endif 92e130fbe2SArthur O'Dwyer 93e130fbe2SArthur O'Dwyer return true; 94a5c3485aSMarshall Clow } 95a5c3485aSMarshall Clow 96504bc07dSLouis Dionne int main(int, char**) 97a5c3485aSMarshall Clow { 98a5c3485aSMarshall Clow { 99a5c3485aSMarshall Clow auto lambda = [](auto x) -> decltype(std::rotl(x, 1U)) {}; 100a5c3485aSMarshall Clow using L = decltype(lambda); 101a5c3485aSMarshall Clow 102e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, signed char>); 103e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, short>); 104e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, int>); 105e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, long>); 106e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, long long>); 1078f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 108e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, __int128_t>); 109a5c3485aSMarshall Clow #endif 110a5c3485aSMarshall Clow 111bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int8_t>); 112bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int16_t>); 113bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int32_t>); 114bd5d0feeSMark de Wever static_assert(!std::is_invocable_v<L, std::int64_t>); 11592fc93e1SMark de Wever static_assert(!std::is_invocable_v<L, std::intmax_t>); 116d59a43feSMark de Wever static_assert(!std::is_invocable_v<L, std::intptr_t>); 117d8681356SMark de Wever static_assert(!std::is_invocable_v<L, std::ptrdiff_t>); 118e130fbe2SArthur O'Dwyer 119e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, bool>); 120e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char>); 121e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, wchar_t>); 1229027887eSMark de Wever #ifndef TEST_HAS_NO_CHAR8_T 123e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char8_t>); 124e130fbe2SArthur O'Dwyer #endif 125e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char16_t>); 126e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, char32_t>); 127e130fbe2SArthur O'Dwyer 128e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, A>); 129e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, A*>); 130e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, E1>); 131e130fbe2SArthur O'Dwyer static_assert(!std::is_invocable_v<L, E2>); 132a5c3485aSMarshall Clow } 133a5c3485aSMarshall Clow 134e130fbe2SArthur O'Dwyer static_assert(test<unsigned char>()); 135e130fbe2SArthur O'Dwyer static_assert(test<unsigned short>()); 136e130fbe2SArthur O'Dwyer static_assert(test<unsigned int>()); 137e130fbe2SArthur O'Dwyer static_assert(test<unsigned long>()); 138e130fbe2SArthur O'Dwyer static_assert(test<unsigned long long>()); 1398f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 140e130fbe2SArthur O'Dwyer static_assert(test<__uint128_t>()); 141a5c3485aSMarshall Clow #endif 142a5c3485aSMarshall Clow 143bd5d0feeSMark de Wever static_assert(test<std::uint8_t>()); 144bd5d0feeSMark de Wever static_assert(test<std::uint16_t>()); 145da79d6e1SMark de Wever static_assert(test<std::uint32_t>()); 146bd5d0feeSMark de Wever static_assert(test<std::uint64_t>()); 14792fc93e1SMark de Wever static_assert(test<std::uintmax_t>()); 148d59a43feSMark de Wever static_assert(test<std::uintptr_t>()); 149fb855eb9SMark de Wever static_assert(test<std::size_t>()); 150a5c3485aSMarshall Clow 151e130fbe2SArthur O'Dwyer test<unsigned char>(); 152e130fbe2SArthur O'Dwyer test<unsigned short>(); 153e130fbe2SArthur O'Dwyer test<unsigned int>(); 154e130fbe2SArthur O'Dwyer test<unsigned long>(); 155e130fbe2SArthur O'Dwyer test<unsigned long long>(); 1568f972cb0SMark de Wever #ifndef TEST_HAS_NO_INT128 157e130fbe2SArthur O'Dwyer test<__uint128_t>(); 158a5c3485aSMarshall Clow #endif 159a5c3485aSMarshall Clow 160bd5d0feeSMark de Wever test<std::uint8_t>(); 161bd5d0feeSMark de Wever test<std::uint16_t>(); 162da79d6e1SMark de Wever test<std::uint32_t>(); 163bd5d0feeSMark de Wever test<std::uint64_t>(); 16492fc93e1SMark de Wever test<std::uintmax_t>(); 165d59a43feSMark de Wever test<std::uintptr_t>(); 166fb855eb9SMark de Wever test<std::size_t>(); 167e130fbe2SArthur O'Dwyer 168504bc07dSLouis Dionne return 0; 169a5c3485aSMarshall Clow } 170