fork download
  1. #include <iostream>
  2. #include <array>
  3. #include <limits>
  4. #include <string>
  5. #include <tuple>
  6. #include <vector>
  7. #include <functional>
  8.  
  9. template<class Tx, class ... Tr> class VariantIndex;
  10.  
  11. template<class Tx> class VariantIndex<Tx>
  12. {
  13. public:
  14. private:
  15. };
  16.  
  17. template<class Tx, class ... Tr> class VariantIndex<Tx, Tx, Tr ...>
  18. {
  19. public:
  20. static constexpr std::size_t index = 1;
  21. private:
  22. };
  23.  
  24. template<class Tx, class Ty, class ... Tr> class VariantIndex<Tx, Ty, Tr ...>
  25. {
  26. public:
  27. static constexpr std::size_t index = VariantIndex<Tx, Tr ...>::index + 1;
  28. private:
  29. };
  30.  
  31. template<class ... Tl>
  32. class Variant
  33. {
  34. public:
  35. Variant()
  36. : m_Type(0)
  37. , m_Deleter(nullptr)
  38. , m_Data(nullptr)
  39. {
  40. }
  41.  
  42. ~Variant()
  43. {
  44. if(m_Type && m_Deleter && m_Data)
  45. {
  46. m_Deleter(m_Data);
  47. }
  48. else
  49. {
  50. if(m_Type || m_Deleter || m_Data)
  51. {
  52. //LOG << "Type, deleter and data must be set together.";
  53. }
  54. }
  55. }
  56.  
  57. template<class T> static Variant MakeByType(const T& t)
  58. {
  59. return Make<VariantIndex<T, Tl ...>::index, T>(t);
  60. }
  61. std::size_t m_Type; ///< Index of type.
  62. std::function<void(void*)> m_Deleter; ///<
  63. void *m_Data; ///< Pointer to data.
  64.  
  65. template<class T> bool IsType() const
  66. {
  67. return m_Type == VariantIndex<T, Tl ...>::index;
  68. }
  69.  
  70. template<class T> const T& GetType() const
  71. {
  72. return *reinterpret_cast<const T*>(m_Data);
  73. }
  74. private:
  75. template<std::size_t I, class T> static Variant Make(const T& t)
  76. {
  77. return Variant(I, [](void *ptr){ std::cout << "Delete type " << I << std::endl; delete reinterpret_cast<T*>(ptr); }, new T(t));
  78. }
  79. Variant(std::size_t type, std::function<void(void*)>&& deleter, void *data)
  80. : m_Type(type)
  81. , m_Deleter(std::move(deleter))
  82. , m_Data(data)
  83. {
  84. }
  85. };
  86.  
  87.  
  88. typedef Variant<int, std::string, char> TestVar;
  89.  
  90. int main(int,char**)
  91. {
  92. TestVar v = TestVar::MakeByType<int>('a');
  93. std::cout << v.m_Type << std::endl;
  94. if(v.IsType<int>())
  95. {
  96. std::cout << "int: " << v.GetType<int>() << std::endl;
  97. }
  98. return 0;
  99. }
Success #stdin #stdout 0s 2988KB
stdin
Standard input is empty
stdout
1
int: 97
Delete type 1