fork download
  1. #include <iostream>
  2. #include <type_traits>
  3. #include <cstring>
  4. #include <typeinfo>
  5.  
  6. using namespace std;
  7.  
  8. template <size_t O,size_t I,size_t C,typename...>
  9. struct byte_offset_impl;
  10.  
  11. template <size_t O,size_t I,size_t C,typename T,typename... Ts>
  12. struct byte_offset_impl< O, I, C,T,Ts...> :
  13. std::conditional<I == C,
  14. std::integral_constant<size_t,O>,
  15. byte_offset_impl<O + sizeof(T),I,C+1,Ts...>
  16. >::type
  17. {};
  18.  
  19.  
  20. template <typename T>
  21. struct type_c
  22. { using type = T; };
  23.  
  24. template <size_t I,size_t C,typename...>
  25. struct type_at_impl;
  26.  
  27. template <size_t I,size_t C,typename T,typename... Ts>
  28. struct type_at_impl<I, C,T,Ts...> :
  29. std::conditional<I == C,
  30. type_c<T>,
  31. type_at_impl<I,C+1,Ts...>
  32. >::type
  33. {};
  34.  
  35.  
  36. template <size_t I,typename... Ts>
  37. constexpr size_t byte_offset = byte_offset_impl<0,I,0,Ts...>::value;
  38.  
  39. template <size_t I,typename... Ts>
  40. using type_at = typename type_at_impl<I,0,Ts...>::type;
  41.  
  42. template <typename...Ts>
  43. struct generic_class
  44. {
  45. generic_class(char* byteptr) : byteptr_(byteptr)
  46. {};
  47.  
  48.  
  49. template <size_t I>
  50. auto get() -> type_at<I, Ts...>& // needed for c++11
  51. {
  52. using result_type = type_at<I, Ts...>;
  53. return *reinterpret_cast<result_type*>(&byteptr_[byte_offset<I, Ts...>]);
  54.  
  55. }
  56.  
  57. template <size_t I>
  58. auto get_v() -> type_at<I, Ts...> // needed for c++11
  59. {
  60. using result_type = type_at<I, Ts...>;
  61. result_type result;
  62.  
  63. std::memcpy(&result, &byteptr_[byte_offset<I, Ts...>], sizeof(result_type));
  64.  
  65. return result;
  66. }
  67. char* byteptr_;
  68. };
  69.  
  70.  
  71. int main() {
  72.  
  73. char bytes[sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint16_t)];
  74.  
  75. uint32_t u32 = 1561;
  76. uint8_t u8 = 22;
  77. uint16_t u16 = 99;
  78.  
  79. char* bytesp = bytes;
  80. std::memcpy(bytesp, &u32, sizeof(uint32_t)); bytesp += sizeof(uint32_t);
  81. std::memcpy(bytesp, &u8, sizeof(uint8_t)); bytesp += sizeof(uint8_t);
  82. std::memcpy(bytesp, &u16, sizeof(uint16_t));
  83.  
  84. generic_class<uint32_t, uint8_t, uint16_t> gen(bytes);
  85. std::cout << (uint32_t)gen.get<0>() << std::endl;
  86. std::cout << (uint32_t)gen.get<1>() << std::endl;
  87. std::cout << (uint32_t)gen.get<2>() << std::endl;
  88.  
  89. std::cout << (uint32_t)gen.get_v<0>() << std::endl;
  90. std::cout << (uint32_t)gen.get_v<1>() << std::endl;
  91. std::cout << (uint32_t)gen.get_v<2>() << std::endl;
  92. }
Success #stdin #stdout 0s 4304KB
stdin
Standard input is empty
stdout
1561
22
99
1561
22
99