Skip to content

Instantly share code, notes, and snippets.

@oktal
Created May 13, 2013 20:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oktal/5571031 to your computer and use it in GitHub Desktop.
Save oktal/5571031 to your computer and use it in GitHub Desktop.
Compile-time binary conversion with variadic templates
#include <iostream>
#include <type_traits>
#include <cassert>
namespace details {
template<typename T> struct DigitValue {
};
template<> struct DigitValue<int> {
static constexpr int v(const int value) { return value; }
};
template<> struct DigitValue<char> {
static constexpr int v(const char value) { return value - '0'; }
};
}
template<unsigned Result, typename Vals, Vals ...digits> struct BinaryConverterBase {
};
template<unsigned Result, typename Vals, Vals Head, Vals ...Tail>
struct BinaryConverterBase<Result, Vals, Head, Tail...> {
static constexpr unsigned value = BinaryConverterBase<2 * Result + details::DigitValue<Vals>::v(Head),
Vals, Tail...>::value;
};
template<unsigned Result, typename Vals> struct BinaryConverterBase<Result, Vals> {
static constexpr unsigned value = Result;
};
template<typename T, T ...digits> struct BinaryConverter : public BinaryConverterBase<0, T, digits...>
{
};
template<char ...digits> constexpr unsigned operator"" _b() {
return BinaryConverter<char, digits...>::value;
}
static_assert(BinaryConverter<0>::value == 0, "0b != 0");
static_assert(BinaryConverter<0, 1, 1, 1>::value == 7, "0111b != 7");
static_assert(BinaryConverter<1, 0, 1, 1>::value == 11, "1011b != 11");
static_assert(BinaryConverter<char, '0'>::value == 0, "0b != 0");
static_assert(BinaryConverter<char, '0','1', '1', '1'>::value == 7, "0111b != 7");
static_assert(BinaryConverter<char, '1', '0', '1', '1'>::value == 11, "1011b != 11");
int main() {
assert(0111_b == 0x7);
assert(11111111_b == 0xFF);
assert(10101010_b == 0xAA);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment