blob: de6ec3b24ecd7616aab4469bab1afebf6a31531a [file] [log] [blame]
Marshall Clowa5c34852019-07-01 23:00:32 +00001//===----------------------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Louis Dionne31cbe0f2020-06-01 10:38:23 -04009// UNSUPPORTED: c++03, c++11, c++14, c++17
Marshall Clowa5c34852019-07-01 23:00:32 +000010
11// template <class T>
12// constexpr T log2p1(T x) noexcept;
13
14// If x == 0, 0; otherwise one plus the base-2 logarithm of x, with any fractional part discarded.
15
Louis Dionne6b77ebd2019-10-23 10:40:15 -070016// Remarks: This function shall not participate in overload resolution unless
Marshall Clowa5c34852019-07-01 23:00:32 +000017// T is an unsigned integer type
18
19#include <bit>
20#include <cstdint>
21#include <cassert>
22
23#include "test_macros.h"
24
25class A{};
26enum E1 : unsigned char { rEd };
27enum class E2 : unsigned char { red };
28
29template <typename T>
30constexpr bool constexpr_test()
31{
32 return std::log2p1(T(0)) == T(0)
33 && std::log2p1(T(1)) == T(1)
34 && std::log2p1(T(2)) == T(2)
35 && std::log2p1(T(3)) == T(2)
36 && std::log2p1(T(4)) == T(3)
37 && std::log2p1(T(5)) == T(3)
38 && std::log2p1(T(6)) == T(3)
39 && std::log2p1(T(7)) == T(3)
40 && std::log2p1(T(8)) == T(4)
41 && std::log2p1(T(9)) == T(4)
42 ;
43}
44
45
46template <typename T>
47void runtime_test()
48{
49 ASSERT_SAME_TYPE(T, decltype(std::log2p1(T(0))));
50 ASSERT_NOEXCEPT( std::log2p1(T(0)));
Stephan T. Lavavej7c9844b2019-10-23 11:45:36 -070051
Marshall Clowa5c34852019-07-01 23:00:32 +000052 assert( std::log2p1(T(0)) == T(0));
53 assert( std::log2p1(T(1)) == T(1));
54 assert( std::log2p1(T(2)) == T(2));
55 assert( std::log2p1(T(3)) == T(2));
56 assert( std::log2p1(T(4)) == T(3));
57 assert( std::log2p1(T(5)) == T(3));
58 assert( std::log2p1(T(6)) == T(3));
59 assert( std::log2p1(T(7)) == T(3));
60 assert( std::log2p1(T(8)) == T(4));
61 assert( std::log2p1(T(9)) == T(4));
62
63
64 assert( std::log2p1(T(121)) == T(7));
65 assert( std::log2p1(T(122)) == T(7));
66 assert( std::log2p1(T(123)) == T(7));
67 assert( std::log2p1(T(124)) == T(7));
68 assert( std::log2p1(T(125)) == T(7));
69 assert( std::log2p1(T(126)) == T(7));
70 assert( std::log2p1(T(127)) == T(7));
71 assert( std::log2p1(T(128)) == T(8));
72 assert( std::log2p1(T(129)) == T(8));
73 assert( std::log2p1(T(130)) == T(8));
74}
75
76int main()
77{
Stephan T. Lavavej7c9844b2019-10-23 11:45:36 -070078
Marshall Clowa5c34852019-07-01 23:00:32 +000079 {
80 auto lambda = [](auto x) -> decltype(std::log2p1(x)) {};
81 using L = decltype(lambda);
Louis Dionne6b77ebd2019-10-23 10:40:15 -070082
Marshall Clowa5c34852019-07-01 23:00:32 +000083 static_assert( std::is_invocable_v<L, unsigned char>, "");
84 static_assert( std::is_invocable_v<L, unsigned int>, "");
85 static_assert( std::is_invocable_v<L, unsigned long>, "");
86 static_assert( std::is_invocable_v<L, unsigned long long>, "");
87
88 static_assert( std::is_invocable_v<L, uint8_t>, "");
89 static_assert( std::is_invocable_v<L, uint16_t>, "");
90 static_assert( std::is_invocable_v<L, uint32_t>, "");
91 static_assert( std::is_invocable_v<L, uint64_t>, "");
92 static_assert( std::is_invocable_v<L, size_t>, "");
93
94 static_assert( std::is_invocable_v<L, uintmax_t>, "");
95 static_assert( std::is_invocable_v<L, uintptr_t>, "");
96
97
98 static_assert(!std::is_invocable_v<L, int>, "");
99 static_assert(!std::is_invocable_v<L, signed int>, "");
100 static_assert(!std::is_invocable_v<L, long>, "");
101 static_assert(!std::is_invocable_v<L, long long>, "");
102
103 static_assert(!std::is_invocable_v<L, int8_t>, "");
104 static_assert(!std::is_invocable_v<L, int16_t>, "");
105 static_assert(!std::is_invocable_v<L, int32_t>, "");
106 static_assert(!std::is_invocable_v<L, int64_t>, "");
107 static_assert(!std::is_invocable_v<L, ptrdiff_t>, "");
108
109 static_assert(!std::is_invocable_v<L, bool>, "");
110 static_assert(!std::is_invocable_v<L, signed char>, "");
111 static_assert(!std::is_invocable_v<L, char16_t>, "");
112 static_assert(!std::is_invocable_v<L, char32_t>, "");
113
114#ifndef _LIBCPP_HAS_NO_INT128
115 static_assert( std::is_invocable_v<L, __uint128_t>, "");
116 static_assert(!std::is_invocable_v<L, __int128_t>, "");
117#endif
Louis Dionne6b77ebd2019-10-23 10:40:15 -0700118
Marshall Clowa5c34852019-07-01 23:00:32 +0000119 static_assert(!std::is_invocable_v<L, A>, "");
120 static_assert(!std::is_invocable_v<L, E1>, "");
121 static_assert(!std::is_invocable_v<L, E2>, "");
122 }
123
124 static_assert(constexpr_test<unsigned char>(), "");
125 static_assert(constexpr_test<unsigned short>(), "");
126 static_assert(constexpr_test<unsigned>(), "");
127 static_assert(constexpr_test<unsigned long>(), "");
128 static_assert(constexpr_test<unsigned long long>(), "");
129
130 static_assert(constexpr_test<uint8_t>(), "");
131 static_assert(constexpr_test<uint16_t>(), "");
132 static_assert(constexpr_test<uint32_t>(), "");
133 static_assert(constexpr_test<uint64_t>(), "");
134 static_assert(constexpr_test<size_t>(), "");
135 static_assert(constexpr_test<uintmax_t>(), "");
136 static_assert(constexpr_test<uintptr_t>(), "");
137
138#ifndef _LIBCPP_HAS_NO_INT128
139 static_assert(constexpr_test<__uint128_t>(), "");
140#endif
141
142
143 runtime_test<unsigned char>();
144 runtime_test<unsigned>();
145 runtime_test<unsigned short>();
146 runtime_test<unsigned long>();
147 runtime_test<unsigned long long>();
148
149 runtime_test<uint8_t>();
150 runtime_test<uint16_t>();
151 runtime_test<uint32_t>();
152 runtime_test<uint64_t>();
153 runtime_test<size_t>();
154 runtime_test<uintmax_t>();
155 runtime_test<uintptr_t>();
156
157#ifndef _LIBCPP_HAS_NO_INT128
158 runtime_test<__uint128_t>();
159
160 {
161 __uint128_t val = 128;
162 val <<= 32;
163 assert( std::log2p1(val-1) == 39);
164 assert( std::log2p1(val) == 40);
165 assert( std::log2p1(val+1) == 40);
166 val <<= 2;
167 assert( std::log2p1(val-1) == 41);
168 assert( std::log2p1(val) == 42);
169 assert( std::log2p1(val+1) == 42);
170 val <<= 3;
171 assert( std::log2p1(val-1) == 44);
172 assert( std::log2p1(val) == 45);
173 assert( std::log2p1(val+1) == 45);
174 }
175#endif
176
177}