Created
February 15, 2013 20:32
-
-
Save bananu7/4963322 to your computer and use it in GitHub Desktop.
Bit operations from Robot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template <int Size> | |
struct uint_least : uint_least<Size+1> {}; | |
template <> | |
struct uint_least<8> : identity<u8> {}; | |
template <> | |
struct uint_least<16> : identity<u16> {}; | |
template <> | |
struct uint_least<32> : identity<u32> {}; | |
template <> | |
struct uint_least<64> : identity<u64> {}; | |
template <int Size> | |
using UintLeast = typename uint_least<Size>::type; | |
template <int Size> | |
struct uint { | |
public: | |
using value_type = UintLeast<Size>; | |
constexpr uint() : value{} {} | |
constexpr uint(value_type value); | |
constexpr operator value_type() const { return value; } | |
private: | |
value_type value; | |
}; | |
using bit = uint<1>; | |
template <int Size> | |
constexpr uint<Size> zigamorph() { | |
return -1; | |
} | |
namespace detail { | |
// this is here to avoid warnings about shifts larger than width | |
constexpr u64 shift_right(u64 value, int n) { | |
return n == 64? 0 : (value << n); | |
} | |
template <int Size> | |
struct zigamorph { | |
static constexpr UintLeast<Size> get() { | |
return shift_right(1, Size) - 1; | |
} | |
}; | |
} // namespace detail | |
template <int Size> | |
constexpr uint<Size>::uint(value_type value) | |
: value(value & detail::zigamorph<Size>::get()) {} | |
template <int First, int Last = First> | |
constexpr uint<Last-First+1> bits(u64 value) { | |
return (value >> First) & zigamorph<Last-First+1>(); | |
} | |
template <int N> | |
constexpr uint<N> bitfield(uint<N> u) { return u; } | |
template <int Head, int... Tail> | |
constexpr uint<sum<Head, Tail...>::value> bitfield(uint<Head> head, uint<Tail>... tail) { | |
return (u64(head) << sum<Tail...>::value) | bitfield(tail...); | |
} | |
template <int First, int Last = First, typename Uint> | |
constexpr Uint with_bits(Uint u, uint<Last-First+1> b) { | |
return bitfield(bits<0,First-1>(u), b, bits<Last+1,63>(u)); | |
} | |
template <typename Uint> | |
constexpr Uint set_bit(Uint u, u8 bit) { | |
return u | (1 << bit); | |
} | |
template <typename Uint> | |
constexpr Uint clear_bit(Uint u, u8 bit) { | |
return u & ~(1 << bit); | |
} | |
template <typename Uint> | |
constexpr Uint toggle_bit(Uint u, u8 bit) { | |
return u ^ (1 << bit); | |
} | |
template <typename Uint> | |
constexpr bool is_bit_set(Uint u, u8 bit) { | |
return u & (1 << bit); | |
} | |
template <int Align, typename Uint> | |
constexpr Uint align_backward(Uint u) { | |
return u & ~zigamorph<Align>(); | |
} | |
template <int Align, typename Uint> | |
constexpr Uint align_forward(Uint u) { | |
return align_backward<Align>(u + zigamorph<Align>()); | |
} | |
constexpr bool is_power_of_two(u32 n) { | |
return n && !(n & (n-1)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment