@@ -96,23 +96,6 @@ _NODISCARD constexpr _Ty rotr(const _Ty _Val, const int _Rotation) noexcept {
96
96
}
97
97
}
98
98
99
- // Implementation of popcount without using specialized CPU instructions.
100
- // Used at compile time and when said instructions are not supported.
101
- template <class _Ty>
102
- _NODISCARD constexpr int _Popcount_fallback(_Ty _Val) noexcept {
103
- constexpr int _Digits = numeric_limits<_Ty>::digits;
104
- // we static_cast these bit patterns in order to truncate them to the correct size
105
- _Val = static_cast<_Ty>(_Val - ((_Val >> 1) & static_cast<_Ty>(0x5555'5555'5555'5555ull)));
106
- _Val = static_cast<_Ty>((_Val & static_cast<_Ty>(0x3333'3333'3333'3333ull))
107
- + ((_Val >> 2) & static_cast<_Ty>(0x3333'3333'3333'3333ull)));
108
- _Val = static_cast<_Ty>((_Val + (_Val >> 4)) & static_cast<_Ty>(0x0F0F'0F0F'0F0F'0F0Full));
109
- for (int _Shift_digits = 8; _Shift_digits < _Digits; _Shift_digits <<= 1) {
110
- _Val = static_cast<_Ty>(_Val + static_cast<_Ty>(_Val >> _Shift_digits));
111
- }
112
- // we want the bottom "slot" that's big enough to store _Digits
113
- return static_cast<int>(_Val & static_cast<_Ty>(_Digits + _Digits - 1));
114
- }
115
-
116
99
#if defined(_M_IX86) || (defined(_M_X64) && !defined(_M_ARM64EC))
117
100
118
101
extern "C" {
@@ -184,32 +167,8 @@ _NODISCARD int _Checked_x86_x64_countl_zero(const _Ty _Val) noexcept {
184
167
}
185
168
#endif // __AVX2__
186
169
}
187
-
188
- template <class _Ty>
189
- _NODISCARD int _Checked_x86_x64_popcount(const _Ty _Val) noexcept {
190
- constexpr int _Digits = numeric_limits<_Ty>::digits;
191
- #ifndef __AVX__
192
- const bool _Definitely_have_popcnt = __isa_available >= __ISA_AVAILABLE_SSE42;
193
- if (!_Definitely_have_popcnt) {
194
- return _Popcount_fallback(_Val);
195
- }
196
- #endif // !defined(__AVX__)
197
-
198
- if constexpr (_Digits <= 16) {
199
- return static_cast<int>(__popcnt16(_Val));
200
- } else if constexpr (_Digits == 32) {
201
- return static_cast<int>(__popcnt(_Val));
202
- } else {
203
- #ifdef _M_IX86
204
- return static_cast<int>(__popcnt(_Val >> 32) + __popcnt(static_cast<unsigned int>(_Val)));
205
- #else // ^^^ _M_IX86 / !_M_IX86 vvv
206
- return static_cast<int>(__popcnt64(_Val));
207
- #endif // _M_IX86
208
- }
209
- }
210
170
#endif // defined(_M_IX86) || (defined(_M_X64) && !defined(_M_ARM64EC))
211
171
212
-
213
172
#if defined(_M_ARM) || defined(_M_ARM64)
214
173
#ifdef __clang__ // TRANSITION, GH-1586
215
174
_NODISCARD constexpr int _Clang_arm_arm64_countl_zero(const unsigned short _Val) {
@@ -283,14 +242,9 @@ _NODISCARD constexpr int countr_one(const _Ty _Val) noexcept {
283
242
return _Countr_zero(static_cast<_Ty>(~_Val));
284
243
}
285
244
286
- template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> _Enabled = 0>
245
+ template <class _Ty, enable_if_t<_Is_standard_unsigned_integer<_Ty>, int> = 0>
287
246
_NODISCARD constexpr int popcount(const _Ty _Val) noexcept {
288
- #if defined(_M_IX86) || (defined(_M_X64) && !defined(_M_ARM64EC))
289
- if (!_STD is_constant_evaluated()) {
290
- return _Checked_x86_x64_popcount(_Val);
291
- }
292
- #endif // defined(_M_IX86) || (defined(_M_X64) && !defined(_M_ARM64EC))
293
- return _Popcount_fallback(_Val);
247
+ return _Popcount(_Val);
294
248
}
295
249
296
250
enum class endian { little = 0, big = 1, native = little };
0 commit comments