File indexing completed on 2026-11-07 10:37:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef XSIMD_CPUID_UTILS_HPP
0013 #define XSIMD_CPUID_UTILS_HPP
0014
0015 #include <cassert>
0016 #include <type_traits>
0017
0018 namespace xsimd
0019 {
0020 namespace utils
0021 {
0022 template <typename I>
0023 constexpr I make_bit_mask(I bit)
0024 {
0025 static_assert(std::is_unsigned<I>::value, "Bit operations must be done on unsigned integers");
0026 assert(bit < static_cast<I>(8 * sizeof(I)));
0027 return static_cast<I>(I { 1 } << bit);
0028 }
0029
0030 template <typename I, typename... Args>
0031 constexpr I make_bit_mask(I bit, Args... bits)
0032 {
0033
0034 static_assert(std::is_unsigned<I>::value, "Bit operations must be done on unsigned integers");
0035 return make_bit_mask<I>(bit) | make_bit_mask<I>(static_cast<I>(bits)...);
0036 }
0037
0038 template <int... Bits, typename I>
0039 constexpr bool all_bits_set(I value)
0040 {
0041 static_assert(std::is_unsigned<I>::value, "Bit operations must be done on unsigned integers");
0042 constexpr I mask = make_bit_mask<I>(static_cast<I>(Bits)...);
0043 return (value & mask) == mask;
0044 }
0045
0046 template <int Bit, typename I>
0047 constexpr I set_bit(I value)
0048 {
0049 static_assert(std::is_unsigned<I>::value, "Bit operations must be done on unsigned integers");
0050 constexpr I mask = make_bit_mask<I>(static_cast<I>(Bit));
0051 return value | mask;
0052 }
0053
0054
0055
0056
0057 template <typename I>
0058 constexpr I make_low_mask(I width) noexcept
0059 {
0060 static_assert(std::is_unsigned<I>::value, "Bit operations must be done on unsigned integers");
0061 assert(width <= static_cast<I>(8 * sizeof(I)));
0062 if (width == static_cast<I>(8 * sizeof(I)))
0063 {
0064 return ~I { 0 };
0065 }
0066 return (I { 1 } << width) - I { 1 };
0067 }
0068
0069
0070 template <typename K, typename U>
0071 struct uint_bitset
0072 {
0073
0074 using storage_type = U;
0075
0076 using key_type = K;
0077
0078
0079 constexpr explicit uint_bitset(storage_type bitset = {}) noexcept
0080 : m_bitset(bitset)
0081 {
0082 }
0083
0084
0085 template <key_type... bits>
0086 constexpr bool all_bits_set() const noexcept
0087 {
0088 return utils::all_bits_set<static_cast<storage_type>(bits)...>(m_bitset);
0089 }
0090
0091
0092 template <key_type bit>
0093 constexpr bool bit_is_set() const noexcept
0094 {
0095 return all_bits_set<bit>();
0096 }
0097
0098
0099 template <key_type bit>
0100 constexpr void set_bit() noexcept
0101 {
0102 m_bitset = utils::set_bit<static_cast<storage_type>(bit)>(m_bitset);
0103 }
0104
0105
0106 template <key_type start, key_type end>
0107 constexpr storage_type get_range() const noexcept
0108 {
0109 constexpr storage_type start_bit = static_cast<storage_type>(start);
0110 constexpr storage_type end_bit = static_cast<storage_type>(end);
0111 constexpr storage_type width = end_bit - start_bit;
0112 constexpr storage_type mask = make_low_mask<storage_type>(width);
0113 return (m_bitset >> start_bit) & mask;
0114 }
0115
0116 private:
0117 storage_type m_bitset = { 0 };
0118 };
0119 }
0120 }
0121
0122 #endif