make masking functions only work for integral types

This commit is contained in:
Ben Merritt 2018-06-16 15:12:31 -07:00
parent 3ca4cdb37a
commit e267a9216d
No known key found for this signature in database
GPG Key ID: F8AD20ED4E6239B7
1 changed files with 7 additions and 3 deletions

View File

@ -1,12 +1,15 @@
#include <cstddef>
#include <type_traits>
// Returns an instance of T with the given number of bits set to 1, starting at the given offset
template<typename T> constexpr T mask(size_t num_bits, size_t offset = 0) {
template<typename T>
constexpr typename std::enable_if<std::is_integral<T>::value, T>::type mask(size_t num_bits, size_t offset = 0) {
return (((T)1 << num_bits) - 1) << offset;
}
// Returns the given number of bits from the data parameter, starting at the given offset
template<typename T> constexpr T get_masked(T data, size_t num_bits, size_t offset) {
template<typename T>
constexpr typename std::enable_if<std::is_integral<T>::value, T>::type get_masked(T data, size_t num_bits, size_t offset) {
return (data >> offset) & mask<T>(num_bits);
}
@ -15,6 +18,7 @@ template<typename T> constexpr T get_masked(T data, size_t num_bits, size_t offs
* set to match the given binary value
*/
//TODO: support typeof(data) != typeof(value)?
template<typename T> constexpr T set_masked(T data, T value, size_t num_bits, size_t offset) {
template<typename T>
constexpr typename std::enable_if<std::is_integral<T>::value, T>::type set_masked(T data, T value, size_t num_bits, size_t offset) {
return (data & ~mask<T>(num_bits, offset)) | ((value & mask<T>(num_bits)) << offset);
}