#include <limits.h>
#include <iostream>
using namespace std;
template<size_t> struct ChooseImpl;
template<> struct ChooseImpl<1> { typedef unsigned char type; };
template<> struct ChooseImpl<2> { typedef uint16_t type; };
template<> struct ChooseImpl<3> { typedef uint32_t type; };
template<> struct ChooseImpl<4> { typedef uint32_t type; };
template<> struct ChooseImpl<5> { typedef uint64_t type; };
template<> struct ChooseImpl<6> { typedef uint64_t type; };
template<> struct ChooseImpl<7> { typedef uint64_t type; };
template<> struct ChooseImpl<8> { typedef uint64_t type; };
template<size_t N0, size_t... Ns>
struct Max
{
static const size_t value = N0 >= Max<Ns...>::value ? N0 : Max<Ns...>::value;
};
template<size_t N>
struct Max<N>
{
static const size_t value = N;
};
template<size_t W0, size_t... Ws>
struct Choose
{
typedef typename ChooseImpl<(Max<W0, Ws...>::value + CHAR_BIT - 1) / CHAR_BIT>::type type;
};
template<typename T, bool>
struct AddSigned
{
typedef T type;
};
template<typename T>
struct AddSigned<T, true>
{
typedef typename make_signed<T>::type type;
};
template<size_t W, bool S = false>
struct Bitset
{
typedef typename AddSigned<typename Choose<W>::type, S>::type value_type;
value_type v : W;
};
template<typename, typename, typename...> struct BitField;
template<size_t W0, size_t W1, bool S0, bool S1>
struct BitField<Bitset<W0, S0>, Bitset<W1, S1>>
{
typedef typename Choose<W0, W1>::type value_type;
typename AddSigned<value_type, S0>::type v0 : W0;
typename AddSigned<value_type, S1>::type v1 : W1;
};
template<size_t W0, size_t W1, size_t W2, bool S0, bool S1, bool S2>
struct BitField<Bitset<W0, S0>, Bitset<W1, S1>, Bitset<W2, S2>>
{
typedef typename Choose<W0, W1, W2>::type value_type;
typename AddSigned<value_type, S0>::type v0 : W0;
typename AddSigned<value_type, S1>::type v1 : W1;
typename AddSigned<value_type, S2>::type v2 : W2;
};
template<size_t W0, size_t W1, size_t W2, size_t W3, bool S0, bool S1, bool S2, bool S3>
struct BitField<Bitset<W0, S0>, Bitset<W1, S1>, Bitset<W2, S2>, Bitset<W3, S3>>
{
typedef typename Choose<W0, W1, W2, W3>::type value_type;
typename AddSigned<value_type, S0>::type v0 : W0;
typename AddSigned<value_type, S1>::type v1 : W1;
typename AddSigned<value_type, S2>::type v2 : W2;
typename AddSigned<value_type, S3>::type v3 : W3;
};
template<size_t W, bool S>
typename Bitset<W, S>::value_type Get(Bitset<W, S> const &arg)
{
return arg.v;
}
template<size_t W0, size_t W1, size_t... Ws, bool S0, bool S1, bool... Ss>
BitField<Bitset<W0, S0>, Bitset<W1, S1>, Bitset<Ws, Ss>...> MakeBitField(Bitset<W0, S0> const &arg0, Bitset<W1, S1> const &arg1, Bitset<Ws, Ss> const &... args)
{
return{ Get(arg0), Get(arg1), Get(args)... };
}
int main() {
typedef Bitset<4> UInt4;
typedef Bitset<10, true> Int10;
UInt4 a = { 15 };
Int10 b = { -1 };
auto c = MakeBitField(UInt4{ 17 }, Int10{ 512 });
cout << sizeof(a)
<< ' ' << (unsigned)a.v
<< ' ' << sizeof(b)
<< ' ' << b.v
<< ' ' << sizeof(c)
<< ' ' << c.v0
<< ' ' << c.v1
<< endl;
return 0;
}
I2luY2x1ZGUgPGxpbWl0cy5oPgojaW5jbHVkZSA8aW9zdHJlYW0+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0ZW1wbGF0ZTxzaXplX3Q+IHN0cnVjdCBDaG9vc2VJbXBsOwp0ZW1wbGF0ZTw+IHN0cnVjdCBDaG9vc2VJbXBsPDE+IHsgdHlwZWRlZiB1bnNpZ25lZCBjaGFyIHR5cGU7IH07CnRlbXBsYXRlPD4gc3RydWN0IENob29zZUltcGw8Mj4geyB0eXBlZGVmIHVpbnQxNl90IHR5cGU7IH07CnRlbXBsYXRlPD4gc3RydWN0IENob29zZUltcGw8Mz4geyB0eXBlZGVmIHVpbnQzMl90IHR5cGU7IH07CnRlbXBsYXRlPD4gc3RydWN0IENob29zZUltcGw8ND4geyB0eXBlZGVmIHVpbnQzMl90IHR5cGU7IH07CnRlbXBsYXRlPD4gc3RydWN0IENob29zZUltcGw8NT4geyB0eXBlZGVmIHVpbnQ2NF90IHR5cGU7IH07CnRlbXBsYXRlPD4gc3RydWN0IENob29zZUltcGw8Nj4geyB0eXBlZGVmIHVpbnQ2NF90IHR5cGU7IH07CnRlbXBsYXRlPD4gc3RydWN0IENob29zZUltcGw8Nz4geyB0eXBlZGVmIHVpbnQ2NF90IHR5cGU7IH07CnRlbXBsYXRlPD4gc3RydWN0IENob29zZUltcGw8OD4geyB0eXBlZGVmIHVpbnQ2NF90IHR5cGU7IH07Cgp0ZW1wbGF0ZTxzaXplX3QgTjAsIHNpemVfdC4uLiBOcz4Kc3RydWN0IE1heAp7CglzdGF0aWMgY29uc3Qgc2l6ZV90IHZhbHVlID0gTjAgPj0gTWF4PE5zLi4uPjo6dmFsdWUgPyBOMCA6IE1heDxOcy4uLj46OnZhbHVlOwp9OwoKdGVtcGxhdGU8c2l6ZV90IE4+CnN0cnVjdCBNYXg8Tj4KewoJc3RhdGljIGNvbnN0IHNpemVfdCB2YWx1ZSA9IE47Cn07Cgp0ZW1wbGF0ZTxzaXplX3QgVzAsIHNpemVfdC4uLiBXcz4Kc3RydWN0IENob29zZQp7Cgl0eXBlZGVmIHR5cGVuYW1lIENob29zZUltcGw8KE1heDxXMCwgV3MuLi4+Ojp2YWx1ZSArIENIQVJfQklUIC0gMSkgLyBDSEFSX0JJVD46OnR5cGUgdHlwZTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQsIGJvb2w+CnN0cnVjdCBBZGRTaWduZWQKewoJdHlwZWRlZiBUIHR5cGU7Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpzdHJ1Y3QgQWRkU2lnbmVkPFQsIHRydWU+CnsKCXR5cGVkZWYgdHlwZW5hbWUgbWFrZV9zaWduZWQ8VD46OnR5cGUgdHlwZTsKfTsKCnRlbXBsYXRlPHNpemVfdCBXLCBib29sIFMgPSBmYWxzZT4Kc3RydWN0IEJpdHNldAp7Cgl0eXBlZGVmIHR5cGVuYW1lIEFkZFNpZ25lZDx0eXBlbmFtZSBDaG9vc2U8Vz46OnR5cGUsIFM+Ojp0eXBlIHZhbHVlX3R5cGU7CgoJdmFsdWVfdHlwZSB2IDogVzsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lLCB0eXBlbmFtZSwgdHlwZW5hbWUuLi4+IHN0cnVjdCBCaXRGaWVsZDsKCnRlbXBsYXRlPHNpemVfdCBXMCwgc2l6ZV90IFcxLCBib29sIFMwLCBib29sIFMxPgpzdHJ1Y3QgQml0RmllbGQ8Qml0c2V0PFcwLCBTMD4sIEJpdHNldDxXMSwgUzE+Pgp7Cgl0eXBlZGVmIHR5cGVuYW1lIENob29zZTxXMCwgVzE+Ojp0eXBlIHZhbHVlX3R5cGU7CgoJdHlwZW5hbWUgQWRkU2lnbmVkPHZhbHVlX3R5cGUsIFMwPjo6dHlwZSB2MCA6IFcwOwoJdHlwZW5hbWUgQWRkU2lnbmVkPHZhbHVlX3R5cGUsIFMxPjo6dHlwZSB2MSA6IFcxOwp9OwoKdGVtcGxhdGU8c2l6ZV90IFcwLCBzaXplX3QgVzEsIHNpemVfdCBXMiwgYm9vbCBTMCwgYm9vbCBTMSwgYm9vbCBTMj4Kc3RydWN0IEJpdEZpZWxkPEJpdHNldDxXMCwgUzA+LCBCaXRzZXQ8VzEsIFMxPiwgQml0c2V0PFcyLCBTMj4+CnsKCXR5cGVkZWYgdHlwZW5hbWUgQ2hvb3NlPFcwLCBXMSwgVzI+Ojp0eXBlIHZhbHVlX3R5cGU7CgoJdHlwZW5hbWUgQWRkU2lnbmVkPHZhbHVlX3R5cGUsIFMwPjo6dHlwZSB2MCA6IFcwOwoJdHlwZW5hbWUgQWRkU2lnbmVkPHZhbHVlX3R5cGUsIFMxPjo6dHlwZSB2MSA6IFcxOwoJdHlwZW5hbWUgQWRkU2lnbmVkPHZhbHVlX3R5cGUsIFMyPjo6dHlwZSB2MiA6IFcyOwp9OwoKdGVtcGxhdGU8c2l6ZV90IFcwLCBzaXplX3QgVzEsIHNpemVfdCBXMiwgc2l6ZV90IFczLCBib29sIFMwLCBib29sIFMxLCBib29sIFMyLCBib29sIFMzPgpzdHJ1Y3QgQml0RmllbGQ8Qml0c2V0PFcwLCBTMD4sIEJpdHNldDxXMSwgUzE+LCBCaXRzZXQ8VzIsIFMyPiwgQml0c2V0PFczLCBTMz4+CnsKCXR5cGVkZWYgdHlwZW5hbWUgQ2hvb3NlPFcwLCBXMSwgVzIsIFczPjo6dHlwZSB2YWx1ZV90eXBlOwoKCXR5cGVuYW1lIEFkZFNpZ25lZDx2YWx1ZV90eXBlLCBTMD46OnR5cGUgdjAgOiBXMDsKCXR5cGVuYW1lIEFkZFNpZ25lZDx2YWx1ZV90eXBlLCBTMT46OnR5cGUgdjEgOiBXMTsKCXR5cGVuYW1lIEFkZFNpZ25lZDx2YWx1ZV90eXBlLCBTMj46OnR5cGUgdjIgOiBXMjsKCXR5cGVuYW1lIEFkZFNpZ25lZDx2YWx1ZV90eXBlLCBTMz46OnR5cGUgdjMgOiBXMzsKfTsKCnRlbXBsYXRlPHNpemVfdCBXLCBib29sIFM+CnR5cGVuYW1lIEJpdHNldDxXLCBTPjo6dmFsdWVfdHlwZSBHZXQoQml0c2V0PFcsIFM+IGNvbnN0ICZhcmcpCnsKCXJldHVybiBhcmcudjsKfQoKdGVtcGxhdGU8c2l6ZV90IFcwLCBzaXplX3QgVzEsIHNpemVfdC4uLiBXcywgYm9vbCBTMCwgYm9vbCBTMSwgYm9vbC4uLiBTcz4KQml0RmllbGQ8Qml0c2V0PFcwLCBTMD4sIEJpdHNldDxXMSwgUzE+LCBCaXRzZXQ8V3MsIFNzPi4uLj4gTWFrZUJpdEZpZWxkKEJpdHNldDxXMCwgUzA+IGNvbnN0ICZhcmcwLCBCaXRzZXQ8VzEsIFMxPiBjb25zdCAmYXJnMSwgQml0c2V0PFdzLCBTcz4gY29uc3QgJi4uLiBhcmdzKQp7CglyZXR1cm57IEdldChhcmcwKSwgR2V0KGFyZzEpLCBHZXQoYXJncykuLi4gfTsKfQoKaW50IG1haW4oKSB7Cgl0eXBlZGVmIEJpdHNldDw0PiBVSW50NDsKCXR5cGVkZWYgQml0c2V0PDEwLCB0cnVlPiBJbnQxMDsKCVVJbnQ0IGEgPSB7IDE1IH07CglJbnQxMCBiID0geyAtMSB9OwoJYXV0byBjID0gTWFrZUJpdEZpZWxkKFVJbnQ0eyAxNyB9LCBJbnQxMHsgNTEyIH0pOwoJY291dCA8PCBzaXplb2YoYSkKCQk8PCAnICcgPDwgKHVuc2lnbmVkKWEudgoJCTw8ICcgJyA8PCBzaXplb2YoYikKCQk8PCAnICcgPDwgYi52CgkJPDwgJyAnIDw8IHNpemVvZihjKQoJCTw8ICcgJyA8PCBjLnYwCgkJPDwgJyAnIDw8IGMudjEKCQk8PCBlbmRsOwoJcmV0dXJuIDA7Cn0=