2017-11-20 19:17:49 +00:00
|
|
|
#pragma once
|
|
|
|
|
2017-12-12 22:29:37 +00:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
# include <intrin.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __GNUG__
|
|
|
|
# include <x86intrin.h>
|
2021-05-29 09:31:32 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if !(defined(_MSC_VER) || defined(__GNUG__))
|
|
|
|
# include <cassert>
|
2021-01-06 15:30:26 +00:00
|
|
|
# include <bitset>
|
2017-12-12 22:29:37 +00:00
|
|
|
#endif
|
|
|
|
|
2017-12-02 19:01:07 +00:00
|
|
|
namespace EightBit {
|
2019-07-21 10:25:06 +00:00
|
|
|
[[nodiscard]] int countBits(uint8_t value) noexcept;
|
|
|
|
[[nodiscard]] bool oddParity(uint8_t value) noexcept;
|
|
|
|
[[nodiscard]] int findFirstSet(unsigned long value) noexcept;
|
2017-12-02 19:01:07 +00:00
|
|
|
}
|
|
|
|
|
2018-12-01 16:41:39 +00:00
|
|
|
inline int EightBit::countBits(uint8_t value) noexcept {
|
2021-05-29 09:31:32 +00:00
|
|
|
#if defined(_MSC_VER)
|
2018-05-02 01:47:47 +00:00
|
|
|
return __popcnt(value);
|
2021-05-29 09:31:32 +00:00
|
|
|
#elif defined(__GNUG__)
|
|
|
|
return __builtin_popcount(value);
|
2018-05-02 01:47:47 +00:00
|
|
|
#else
|
|
|
|
/*
|
|
|
|
Published in 1988, the C Programming Language 2nd Ed.
|
|
|
|
(by Brian W.Kernighan and Dennis M.Ritchie) mentions
|
|
|
|
this in exercise 2 - 9. On April 19, 2006 Don Knuth pointed
|
|
|
|
out to me that this method "was first published by Peter
|
|
|
|
Wegner in CACM 3 (1960), 322.
|
|
|
|
(Also discovered independently by Derrick Lehmer and published
|
|
|
|
in 1964 in a book edited by Beckenbach.)"
|
|
|
|
*/
|
2017-12-02 19:01:07 +00:00
|
|
|
int count; // c accumulates the total bits set in value
|
|
|
|
for (count = 0; value; ++count)
|
|
|
|
value &= value - 1; // clear the least significant bit set
|
|
|
|
return count;
|
2018-05-02 01:47:47 +00:00
|
|
|
#endif
|
2017-12-02 19:01:07 +00:00
|
|
|
}
|
|
|
|
|
2018-11-28 21:27:14 +00:00
|
|
|
inline bool EightBit::oddParity(const uint8_t value) noexcept {
|
2021-05-29 09:31:32 +00:00
|
|
|
#ifdef __GNUG__
|
|
|
|
return __builtin_parity(value)
|
|
|
|
#else
|
2017-12-02 19:01:07 +00:00
|
|
|
return countBits(value) % 2;
|
2021-05-29 09:31:32 +00:00
|
|
|
#endif
|
2017-12-02 19:01:07 +00:00
|
|
|
}
|
|
|
|
|
2019-07-21 10:25:06 +00:00
|
|
|
inline int EightBit::findFirstSet(const unsigned long value) noexcept {
|
2021-05-29 09:31:32 +00:00
|
|
|
#if defined(_MSC_VER)
|
|
|
|
unsigned long index = 0;
|
2017-12-12 22:29:37 +00:00
|
|
|
if (_BitScanForward(&index, value))
|
|
|
|
return index + 1;
|
|
|
|
return 0;
|
|
|
|
#elif defined(__GNUG__)
|
|
|
|
return __builtin_ffs(value);
|
|
|
|
#else
|
2019-07-21 10:25:06 +00:00
|
|
|
std::bitset<sizeof(unsigned long) * 8> bits(value);
|
|
|
|
for (size_t i = bits.size() - 1; i >= 0; --i)
|
|
|
|
if (bits.test(i))
|
|
|
|
return i + 1;
|
|
|
|
return 0;
|
2017-12-12 22:29:37 +00:00
|
|
|
#endif
|
|
|
|
}
|
2017-11-20 19:17:49 +00:00
|
|
|
|
2021-05-29 09:31:32 +00:00
|
|
|
#define PARITY(x) EightBit::oddParity(x)
|
2018-03-10 01:53:57 +00:00
|
|
|
|
2017-12-12 22:29:37 +00:00
|
|
|
#ifdef _MSC_VER
|
2017-11-20 19:17:49 +00:00
|
|
|
|
2021-05-29 09:31:32 +00:00
|
|
|
# define ASSUME(x) __assume(x);
|
|
|
|
|
2017-11-20 19:17:49 +00:00
|
|
|
# define LIKELY(x) (x)
|
|
|
|
# define UNLIKELY(x) (x)
|
|
|
|
|
2018-11-27 22:36:54 +00:00
|
|
|
# define UNREACHABLE { ASSUME(0); throw std::exception("unreachable"); }
|
2017-11-20 19:17:49 +00:00
|
|
|
|
2017-11-20 20:54:17 +00:00
|
|
|
#elif defined(__GNUG__)
|
2017-11-20 19:17:49 +00:00
|
|
|
|
2021-05-29 09:31:32 +00:00
|
|
|
# define ASSUME(x) { if (!x) __builtin_unreachable(); }
|
|
|
|
|
2017-11-20 19:17:49 +00:00
|
|
|
# define LIKELY(x) __builtin_expect(!!(x), 1)
|
|
|
|
# define UNLIKELY(x) __builtin_expect(!!(x), 0)
|
|
|
|
|
2018-03-10 01:53:57 +00:00
|
|
|
# define UNREACHABLE __builtin_unreachable();
|
2017-11-20 19:17:49 +00:00
|
|
|
|
|
|
|
#else
|
2017-12-02 19:01:07 +00:00
|
|
|
|
2021-05-29 09:31:32 +00:00
|
|
|
# define ASSUME(x) assert(x);
|
|
|
|
|
2017-12-02 19:01:07 +00:00
|
|
|
# define LIKELY(x) (x)
|
|
|
|
# define UNLIKELY(x) (x)
|
|
|
|
|
2018-03-10 01:53:57 +00:00
|
|
|
# define UNREACHABLE ASSUME(0)
|
2017-12-02 19:01:07 +00:00
|
|
|
|
2017-11-20 19:17:49 +00:00
|
|
|
#endif
|