Advertisement
Guest User

Structured bindings for templated class

a guest
Dec 27th, 2017
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.19 KB | None | 0 0
  1. template<typename T, int N, typename... Ts>
  2. struct get_index_in_pack_impl;
  3.  
  4. template<typename T, int N, typename T0, typename... Ts>
  5. struct get_index_in_pack_impl<T, N, T0, Ts...>
  6. {
  7.     static constexpr int value = std::is_same_v<T, T0> ? N : get_index_in_pack_impl<T, (N+1), Ts...>::value;
  8. };
  9.  
  10. template<typename T, int N, typename T0>
  11. struct get_index_in_pack_impl<T, N, T0>
  12. {
  13.     static constexpr int value = std::is_same_v<T, T0> ? N : -1;
  14. };
  15.  
  16. template<typename T, int N>
  17. struct get_index_in_pack_impl<T, N>
  18. {
  19.     static constexpr int value = -1;
  20. };
  21.  
  22. template<size_t I, typename... Pack>
  23. struct n_type_in_pack_impl;
  24.  
  25. template<size_t I, typename T, typename... Pack>
  26. struct n_type_in_pack_impl<I, T, Pack...>
  27. {
  28.     using type = typename n_type_in_pack_impl<I - 1, Pack...>::type;
  29. };
  30.  
  31. template<typename T, typename... Pack>
  32. struct n_type_in_pack_impl<0, T, Pack...>
  33. {
  34.     using type = T;
  35. };
  36.  
  37. template<typename T>
  38. struct n_type_in_pack_impl<0, T>
  39. {
  40.     using type = T;
  41. };
  42.  
  43. template<size_t I, typename... Pack>
  44. using GetTypeInPack = typename n_type_in_pack_impl<I, Pack...>;
  45.  
  46.  
  47. template<typename T, typename... Ts>
  48. using GetIndexInPack = get_index_in_pack_impl < T, 0, Ts... >;
  49.  
  50. template<typename... Cmps>
  51. struct CmpGroup
  52. {
  53.     std::array<void*, sizeof...(Cmps)> cmps;
  54.  
  55.     template<typename C>
  56.     C& get()
  57.     {
  58.         constexpr int index = GetIndexInPack<C, Cmps...>::value;
  59.         static_assert(index != -1, "");
  60.         return *static_cast<C*>(index);
  61.     }
  62.  
  63.     template<size_t I>
  64.     auto& get()
  65.     {
  66.         static_assert(I < sizeof...(Cmps), "");
  67.         using CmpType = typename GetTypeInPack<I, Cmps...>::type;
  68.         return *static_cast<CmpType*>(cmps[I]);
  69.     }
  70. };
  71.  
  72. namespace std
  73. {
  74.     template<typename... Types>
  75.     struct tuple_size<CmpGroup<Types...>> : public integral_constant<size_t, sizeof...(Types)>;
  76.  
  77.     template<std::size_t N, typename... Types>
  78.     struct tuple_element<N, CmpGroup<Types...>> {
  79.         //got this from: https://blog.tartanllama.xyz/structured-bindings/
  80.         using type = decltype(std::declval<CmpGroup<Types...>>().template get<N>());
  81.     };
  82. }
  83.  
  84. int main()
  85. {
  86.     using namespace std;
  87.  
  88.     CmpGroup<int, double, float> cmp_group;
  89.     auto[i, d, f] = cmp_group;
  90.  
  91.     //should not print anything but should compile
  92.     cout << i;
  93. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement