fork(2) download
  1. #include <iostream>
  2. #include <string>
  3. #include <memory>
  4. #include <utility>
  5. #include <cassert>
  6.  
  7. #define GENERATE_META(type) \
  8.   public: \
  9.   static const MetaInfo& StaticMeta() \
  10.   { \
  11.   static MetaInfo meta{#type}; \
  12.   return meta; \
  13.   }
  14.  
  15. struct MetaInfo
  16. {
  17. const std::string _id;
  18.  
  19. explicit MetaInfo( std::string ti )
  20. : _id{std::move( ti )}{}
  21.  
  22. bool operator==(const MetaInfo& rhs) const
  23. {
  24. return _id == rhs._id;
  25. }
  26.  
  27. bool operator!=(const MetaInfo& rhs) const
  28. {
  29. return operator==(rhs);
  30. }
  31. };
  32.  
  33. // Inheritance is just for example
  34. // In real project code is generated by tools
  35. struct Base
  36. {
  37. protected:
  38. Base() = default;
  39. };
  40.  
  41. struct MyType1 : Base
  42. {
  43. GENERATE_META(MyType1)
  44. int _dummy = 1;
  45. };
  46.  
  47. struct MyType2 : Base
  48. {
  49. GENERATE_META(MyType2)
  50. float _dummy = 2.f;
  51. };
  52.  
  53. struct MyType3 : Base
  54. {
  55. GENERATE_META(MyType3)
  56. std::string _dummy = "gg";
  57. };
  58.  
  59.  
  60. class Table
  61. {
  62. public:
  63. template< typename T >
  64. static Table Create()
  65. {
  66. auto data = std::make_shared<T>();
  67. auto meta = &T::StaticMeta();
  68. return { data, meta };
  69. }
  70.  
  71. const std::shared_ptr<Base>& Data() const{ return _data; }
  72. const MetaInfo& Meta() const{ return *_meta; }
  73.  
  74. private:
  75. Table( std::shared_ptr<Base> data, const MetaInfo * meta )
  76. : _data{std::move(data)}
  77. , _meta{meta}
  78. {}
  79.  
  80. private:
  81. std::shared_ptr<Base> _data;
  82. const MetaInfo * const _meta = nullptr;
  83. };
  84.  
  85. template< typename T >
  86. void Print( const Table& table )
  87. {
  88. assert( table.Meta() == T::StaticMeta() );
  89. const auto& data = *static_cast<T*>(table.Data().get());
  90. std::cout << table.Meta()._id << " -> " << data._dummy << "\n";
  91. }
  92.  
  93. /////////////////////////////////////////////////////////////////////
  94.  
  95.  
  96. // проверка одного элемента
  97.  
  98. template< typename T >
  99. bool Validate_1( const Table& table )
  100. {
  101. if ( table.Meta() == T::StaticMeta() )
  102. {
  103. Print<T>( table );
  104. return true;
  105. }
  106.  
  107. return false;
  108. }
  109.  
  110. // проверка списка
  111.  
  112. template< typename T = void, typename ...Tables >
  113. bool Validate( const Table& table )
  114. {
  115. if ( Validate_1<T>( table ) )
  116. return true;
  117.  
  118. return Validate<Tables...>(table);
  119. }
  120.  
  121. template<>
  122. bool Validate( const Table& table ) {
  123. return false;
  124. }
  125.  
  126. int main()
  127. {
  128. const auto t1 = Table::Create<MyType1>();
  129. const auto t2 = Table::Create<MyType2>();
  130. const auto t3 = Table::Create<MyType3>();
  131.  
  132. const auto r1 = Validate<MyType1, MyType2>(t1);
  133. assert( r1 );
  134. const auto r2 = Validate<MyType1, MyType2>(t2);
  135. assert( r2 );
  136. const auto r3 = Validate<MyType1, MyType2>(t3);
  137. assert( !r3 );
  138.  
  139. return 0;
  140. }
Success #stdin #stdout 0s 4404KB
stdin
Standard input is empty
stdout
MyType1 -> 1
MyType2 -> 2