Skip to content

Instantly share code, notes, and snippets.

@kkiningh
Created July 21, 2017 23:21
Show Gist options
  • Save kkiningh/2812b2f349d09ec21fad4cafcbf6bb02 to your computer and use it in GitHub Desktop.
Save kkiningh/2812b2f349d09ec21fad4cafcbf6bb02 to your computer and use it in GitHub Desktop.
A simple class for a fixed size unsigned integer with a specified number of bits
#include <cstdint>
#include <cstddef>
#include <type_traits>
namespace detail {
/* Bit of metaprogramming to select a template based on the size of the
* smallest integer that can represent a integer template parameter */
namespace traits {
template <typename T>
constexpr size_t bitsize(T);
template <>
constexpr size_t bitsize(uint8_t) { return 8; }
template <>
constexpr size_t bitsize(uint16_t) { return 16; }
template <>
constexpr size_t bitsize(uint32_t) { return 32; }
template <>
constexpr size_t bitsize(uint64_t) { return 64; }
};
template <typename T>
struct tag {
using type = T;
};
/* Base case: fail if not found */
template <size_t Size, typename...>
struct MinUnsignedType;
/* Recursive case: check using bitsize helper */
template <size_t Size, typename T, typename... Ts>
struct MinUnsignedType<Size, T, Ts...>
: std::conditional<Size <= traits::bitsize<T>(), T, MinUnsignedType<Size, Ts...>>
{ };
}
/* Alias to allow for easy use */
template <size_t Size>
using MinUnsignedType =
typename detail::MinUnsignedType<Size,
uint8_t, uint16_t, uint32_t, uint64_t>::type;
template <size_t Size>
class Bits {
private:
/* Actual type for storing the value */
using T = typename MinUnsignedType<Size>::type;
/* Mask for the bits we care about in storage */
enum : T {
Mask = (1u << Size) - 1u
};
private:
/* The actual storage for the value */
T value_;
public:
explicit constexpr Bits(T value)
: value_(value)
{ }
static constexpr Bits<T> max() const {
return (1u << Size) - 1u;
}
static constexpr Bits<T> min() const {
return 0;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment