Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-07 10:37:18

0001 /***************************************************************************
0002  * Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and         *
0003  * Martin Renou                                                             *
0004  * Copyright (c) QuantStack                                                 *
0005  * Copyright (c) Serge Guelton                                              *
0006  *                                                                          *
0007  * Distributed under the terms of the BSD 3-Clause License.                 *
0008  *                                                                          *
0009  * The full license is in the file LICENSE, distributed with this software. *
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             // TODO(C++17): Use fold expression
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          * Return a mask with the `width` lowest bits set.
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         /* A bitset over an unsigned integer type, indexed by an enum key type. */
0070         template <typename K, typename U>
0071         struct uint_bitset
0072         {
0073             /* The underlying unsigned integer type storing the bits. */
0074             using storage_type = U;
0075             /* The enum type whose values name individual bits. */
0076             using key_type = K;
0077 
0078             /* Construct from a raw bit pattern. */
0079             constexpr explicit uint_bitset(storage_type bitset = {}) noexcept
0080                 : m_bitset(bitset)
0081             {
0082             }
0083 
0084             /* Return true if every bit named by the template arguments is set. */
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             /* Return true if the bit is set. */
0092             template <key_type bit>
0093             constexpr bool bit_is_set() const noexcept
0094             {
0095                 return all_bits_set<bit>();
0096             }
0097 
0098             /* Set the corresponding bit to true in the bitfield. */
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             /* Extract the bits in [start, end[, shifted down to start at bit 0. */
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