forked from dolphin-emu/dolphin
		
	
		
			
	
	
		
			103 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			103 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | // Copyright 2017 Dolphin Emulator Project
 | ||
|  | // Licensed under GPLv2+
 | ||
|  | // Refer to the license.txt file included.
 | ||
|  | 
 | ||
|  | #pragma once
 | ||
|  | 
 | ||
|  | #include <climits>
 | ||
|  | #include <cstddef>
 | ||
|  | #include <type_traits>
 | ||
|  | 
 | ||
|  | 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 <typename T> | ||
|  | 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 <typename T> | ||
|  | constexpr T ExtractBit(const T src, const size_t bit) noexcept | ||
|  | { | ||
|  |   return (src >> bit) & static_cast<T>(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 <size_t bit, typename T> | ||
|  | constexpr T ExtractBit(const T src) noexcept | ||
|  | { | ||
|  |   static_assert(bit < BitSize<T>(), "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 <typename T, typename Result = std::make_unsigned_t<T>> | ||
|  | constexpr Result ExtractBits(const T src, const size_t begin, const size_t end) noexcept | ||
|  | { | ||
|  |   return static_cast<Result>(((static_cast<Result>(src) << ((BitSize<T>() - 1) - end)) >> | ||
|  |                               (BitSize<T>() - 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 <size_t begin, size_t end, typename T, typename Result = std::make_unsigned_t<T>> | ||
|  | constexpr Result ExtractBits(const T src) noexcept | ||
|  | { | ||
|  |   static_assert(begin < end, "Beginning bit must be less than the ending bit."); | ||
|  |   static_assert(begin < BitSize<T>(), "Beginning bit is larger than T's bit width."); | ||
|  |   static_assert(end < BitSize<T>(), "Ending bit is larger than T's bit width."); | ||
|  | 
 | ||
|  |   return ExtractBits<T, Result>(src, begin, end); | ||
|  | } | ||
|  | }  // namespace Common
 |