// Copyright 2017 Dolphin Emulator Project // Licensed under GPLv2+ // Refer to the license.txt file included. #pragma once #include #include #include namespace Common { /// /// Retrieves the size of a type in bits. /// /// @tparam T Type to get the size of. /// /// @return the size of the type in bits. /// template constexpr size_t BitSize() noexcept { return sizeof(T) * CHAR_BIT; } /// /// Extracts a bit from a value. /// /// @param src The value to extract a bit from. /// @param bit The bit to extract. /// /// @tparam T The type of the value. /// /// @return The extracted bit. /// template constexpr T ExtractBit(const T src, const size_t bit) noexcept { return (src >> bit) & static_cast(1); } /// /// Extracts a bit from a value. /// /// @param src The value to extract a bit from. /// /// @tparam bit The bit to extract. /// @tparam T The type of the value. /// /// @return The extracted bit. /// template constexpr T ExtractBit(const T src) noexcept { static_assert(bit < BitSize(), "Specified bit must be within T's bit width."); return ExtractBit(src, bit); } /// /// Extracts a range of bits from a value. /// /// @param src The value to extract the bits from. /// @param begin The beginning of the bit range. This is inclusive. /// @param end The ending of the bit range. This is inclusive. /// /// @tparam T The type of the value. /// @tparam Result The returned result type. This is the unsigned analog /// of a signed type if a signed type is passed as T. /// /// @return The extracted bits. /// template > constexpr Result ExtractBits(const T src, const size_t begin, const size_t end) noexcept { return static_cast(((static_cast(src) << ((BitSize() - 1) - end)) >> (BitSize() - end + begin - 1))); } /// /// Extracts a range of bits from a value. /// /// @param src The value to extract the bits from. /// /// @tparam begin The beginning of the bit range. This is inclusive. /// @tparam end The ending of the bit range. This is inclusive. /// @tparam T The type of the value. /// @tparam Result The returned result type. This is the unsigned analog /// of a signed type if a signed type is passed as T. /// /// @return The extracted bits. /// template > constexpr Result ExtractBits(const T src) noexcept { static_assert(begin < end, "Beginning bit must be less than the ending bit."); static_assert(begin < BitSize(), "Beginning bit is larger than T's bit width."); static_assert(end < BitSize(), "Ending bit is larger than T's bit width."); return ExtractBits(src, begin, end); } } // namespace Common