#include <iostream>
#include <type_traits>
#include <cstring>
#include <typeinfo>
using namespace std;
template <size_t O,size_t I,size_t C,typename...>
struct byte_offset_impl;
template <size_t O,size_t I,size_t C,typename T,typename... Ts>
struct byte_offset_impl< O, I, C,T,Ts...> :
std::conditional<I == C,
std::integral_constant<size_t,O>,
byte_offset_impl<O + sizeof(T),I,C+1,Ts...>
>::type
{};
template <typename T>
struct type_c
{ using type = T; };
template <size_t I,size_t C,typename...>
struct type_at_impl;
template <size_t I,size_t C,typename T,typename... Ts>
struct type_at_impl<I, C,T,Ts...> :
std::conditional<I == C,
type_c<T>,
type_at_impl<I,C+1,Ts...>
>::type
{};
template <size_t I,typename... Ts>
constexpr size_t byte_offset = byte_offset_impl<0,I,0,Ts...>::value;
template <size_t I,typename... Ts>
using type_at = typename type_at_impl<I,0,Ts...>::type;
template <typename...Ts>
struct generic_class
{
generic_class(char* byteptr) : byteptr_(byteptr)
{};
template <size_t I>
auto get() -> type_at<I, Ts...>& // needed for c++11
{
using result_type = type_at<I, Ts...>;
return *reinterpret_cast<result_type*>(&byteptr_[byte_offset<I, Ts...>]);
}
template <size_t I>
auto get_v() -> type_at<I, Ts...> // needed for c++11
{
using result_type = type_at<I, Ts...>;
result_type result;
std::memcpy(&result, &byteptr_[byte_offset<I, Ts...>], sizeof(result_type));
return result;
}
char* byteptr_;
};
int main() {
char bytes[sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint16_t)];
uint32_t u32 = 1561;
uint8_t u8 = 22;
uint16_t u16 = 99;
char* bytesp = bytes;
std::memcpy(bytesp, &u32, sizeof(uint32_t)); bytesp += sizeof(uint32_t);
std::memcpy(bytesp, &u8, sizeof(uint8_t)); bytesp += sizeof(uint8_t);
std::memcpy(bytesp, &u16, sizeof(uint16_t));
generic_class<uint32_t, uint8_t, uint16_t> gen(bytes);
std::cout << (uint32_t)gen.get<0>() << std::endl;
std::cout << (uint32_t)gen.get<1>() << std::endl;
std::cout << (uint32_t)gen.get<2>() << std::endl;
std::cout << (uint32_t)gen.get_v<0>() << std::endl;
std::cout << (uint32_t)gen.get_v<1>() << std::endl;
std::cout << (uint32_t)gen.get_v<2>() << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDxjc3RyaW5nPgojaW5jbHVkZSA8dHlwZWluZm8+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGUgPHNpemVfdCBPLHNpemVfdCBJLHNpemVfdCBDLHR5cGVuYW1lLi4uPgpzdHJ1Y3QgYnl0ZV9vZmZzZXRfaW1wbDsKCnRlbXBsYXRlIDxzaXplX3QgTyxzaXplX3QgSSxzaXplX3QgQyx0eXBlbmFtZSBULHR5cGVuYW1lLi4uIFRzPgpzdHJ1Y3QgYnl0ZV9vZmZzZXRfaW1wbDwgTywgSSwgQyxULFRzLi4uPiA6IAoJc3RkOjpjb25kaXRpb25hbDxJID09IEMsCgkgIHN0ZDo6aW50ZWdyYWxfY29uc3RhbnQ8c2l6ZV90LE8+LAoJICBieXRlX29mZnNldF9pbXBsPE8gKyBzaXplb2YoVCksSSxDKzEsVHMuLi4+CSAKCT46OnR5cGUKe307CgoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0cnVjdCB0eXBlX2MgCnsgdXNpbmcgdHlwZSA9IFQ7IH07Cgp0ZW1wbGF0ZSA8c2l6ZV90IEksc2l6ZV90IEMsdHlwZW5hbWUuLi4+CnN0cnVjdCB0eXBlX2F0X2ltcGw7Cgp0ZW1wbGF0ZSA8c2l6ZV90IEksc2l6ZV90IEMsdHlwZW5hbWUgVCx0eXBlbmFtZS4uLiBUcz4Kc3RydWN0IHR5cGVfYXRfaW1wbDxJLCBDLFQsVHMuLi4+IDogCglzdGQ6OmNvbmRpdGlvbmFsPEkgPT0gQywKCSAgdHlwZV9jPFQ+LAoJICB0eXBlX2F0X2ltcGw8SSxDKzEsVHMuLi4+CSAKCT46OnR5cGUKe307CgoKdGVtcGxhdGUgPHNpemVfdCBJLHR5cGVuYW1lLi4uIFRzPgpjb25zdGV4cHIgc2l6ZV90IGJ5dGVfb2Zmc2V0ID0gYnl0ZV9vZmZzZXRfaW1wbDwwLEksMCxUcy4uLj46OnZhbHVlOwoKdGVtcGxhdGUgPHNpemVfdCBJLHR5cGVuYW1lLi4uIFRzPgp1c2luZyB0eXBlX2F0ID0gdHlwZW5hbWUgdHlwZV9hdF9pbXBsPEksMCxUcy4uLj46OnR5cGU7Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi5Ucz4Kc3RydWN0IGdlbmVyaWNfY2xhc3MKewoJZ2VuZXJpY19jbGFzcyhjaGFyKiBieXRlcHRyKSA6IGJ5dGVwdHJfKGJ5dGVwdHIpCgl7fTsKCgoJdGVtcGxhdGUgPHNpemVfdCBJPgoJYXV0byBnZXQoKSAtPiB0eXBlX2F0PEksIFRzLi4uPiYgLy8gbmVlZGVkIGZvciBjKysxMQoJewoJCXVzaW5nIHJlc3VsdF90eXBlID0gdHlwZV9hdDxJLCBUcy4uLj47CgkJcmV0dXJuICpyZWludGVycHJldF9jYXN0PHJlc3VsdF90eXBlKj4oJmJ5dGVwdHJfW2J5dGVfb2Zmc2V0PEksIFRzLi4uPl0pOwoKCX0KCgl0ZW1wbGF0ZSA8c2l6ZV90IEk+CglhdXRvIGdldF92KCkgLT4gdHlwZV9hdDxJLCBUcy4uLj4gLy8gbmVlZGVkIGZvciBjKysxMQoJewoJCXVzaW5nIHJlc3VsdF90eXBlID0gdHlwZV9hdDxJLCBUcy4uLj47CgkJcmVzdWx0X3R5cGUgcmVzdWx0OwoKCQlzdGQ6Om1lbWNweSgmcmVzdWx0LCAmYnl0ZXB0cl9bYnl0ZV9vZmZzZXQ8SSwgVHMuLi4+XSwgc2l6ZW9mKHJlc3VsdF90eXBlKSk7CgoJCXJldHVybiByZXN1bHQ7Cgl9CgljaGFyKiBieXRlcHRyXzsKfTsKCgppbnQgbWFpbigpIHsKCgljaGFyIGJ5dGVzW3NpemVvZih1aW50MzJfdCkgKyBzaXplb2YodWludDhfdCkgKyBzaXplb2YodWludDE2X3QpXTsKCgl1aW50MzJfdCB1MzIgPSAxNTYxOwoJdWludDhfdCB1OCA9IDIyOwoJdWludDE2X3QgdTE2ID0gOTk7CgoJY2hhciogYnl0ZXNwID0gYnl0ZXM7CglzdGQ6Om1lbWNweShieXRlc3AsICZ1MzIsIHNpemVvZih1aW50MzJfdCkpOyBieXRlc3AgKz0gc2l6ZW9mKHVpbnQzMl90KTsKCXN0ZDo6bWVtY3B5KGJ5dGVzcCwgJnU4LCBzaXplb2YodWludDhfdCkpOyBieXRlc3AgKz0gc2l6ZW9mKHVpbnQ4X3QpOwoJc3RkOjptZW1jcHkoYnl0ZXNwLCAmdTE2LCBzaXplb2YodWludDE2X3QpKTsKCglnZW5lcmljX2NsYXNzPHVpbnQzMl90LCB1aW50OF90LCB1aW50MTZfdD4gZ2VuKGJ5dGVzKTsKCXN0ZDo6Y291dCA8PCAodWludDMyX3QpZ2VuLmdldDwwPigpIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y291dCA8PCAodWludDMyX3QpZ2VuLmdldDwxPigpIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y291dCA8PCAodWludDMyX3QpZ2VuLmdldDwyPigpIDw8IHN0ZDo6ZW5kbDsKCglzdGQ6OmNvdXQgPDwgKHVpbnQzMl90KWdlbi5nZXRfdjwwPigpIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y291dCA8PCAodWludDMyX3QpZ2VuLmdldF92PDE+KCkgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8ICh1aW50MzJfdClnZW4uZ2V0X3Y8Mj4oKSA8PCBzdGQ6OmVuZGw7Cn0=