Skip to content

Instantly share code, notes, and snippets.

@h-hirai
Last active February 23, 2017 14:27
Show Gist options
  • Save h-hirai/7aaf5660235ba24a762726177a0c360a to your computer and use it in GitHub Desktop.
Save h-hirai/7aaf5660235ba24a762726177a0c360a to your computer and use it in GitHub Desktop.
#include <cstddef>
#include <cstdint>
#include <cassert>
#include <iostream>
template <std::size_t W>
struct BV {
std::uint32_t const value;
explicit constexpr BV(std::uint32_t v) : value(v) {
static_assert(32>=W, "not supported.");
assert((1<<W) > v);
}
template <std::size_t MSB, std::size_t LSB>
constexpr
BV<MSB-LSB+1> slice() const {
static_assert(W>MSB && MSB>=LSB, "range error");
constexpr std::size_t newWid{MSB-LSB+1};
constexpr std::uint32_t mask{(1<<newWid)-1};
return BV<newWid>{(value>>LSB)&mask};
}
};
template <std::size_t V, std::size_t W>
constexpr
BV<V+W> concat_binary(BV<V> const& lhs, BV<W> const& rhs) {
return BV<V+W>{(lhs.value<<W) + rhs.value};
}
constexpr
auto concat() {
return BV<0>{0};
}
template <std::size_t W, typename... Ts>
constexpr
auto concat(BV<W> const& v, Ts... rest) {
return concat_binary(v, concat(rest...));
}
int main() {
std::cout << std::hex;
constexpr BV<8> v58{0x58};
std::cout << v58.value << std::endl;
std::cout << v58.slice<7,4>().value << std::endl;
std::cout << v58.slice<3,0>().value << std::endl;
BV<0> mzero{concat()};
std::cout << mzero.value << std::endl;
auto v8{v58.slice<3,0>()};
std::cout << concat(v8, v8, v58.slice<7,4>()).value << std::endl;
BV<2> v0{false};
BV<2> v1{true};
std::cout << concat(v0, v1).value << std::endl;
std::cout << concat(v1, v0).value << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment