fork(1) download
  1. #include <typeinfo>
  2. #include <memory>
  3. #include <iostream>
  4. #include <string>
  5. using namespace std;
  6.  
  7.  
  8. class TDirectoryEntryPtrBase {
  9. public:
  10. virtual ~TDirectoryEntryPtrBase() {}
  11.  
  12. virtual void* GetObjectAddr() const = 0;
  13.  
  14. virtual const std::type_info& GetTypeInfo() const = 0;
  15.  
  16. template<class U>
  17. U* Cast() const;
  18.  
  19. private:
  20. virtual void CastImpl() const = 0;
  21. };
  22.  
  23. template<class U>
  24. U* TDirectoryEntryPtrBase::Cast() const
  25. {
  26. try{ CastImpl(); }
  27. catch (U* ptr) { return static_cast<U*>(ptr); }
  28. catch (...) {}
  29. return nullptr;
  30. }
  31.  
  32. template <class T>
  33. class TDirectoryEntryPtr: public TDirectoryEntryPtrBase {
  34. public:
  35. TDirectoryEntryPtr(T* obj): fObj(obj) {}
  36.  
  37. TDirectoryEntryPtr(const shared_ptr<T>& ptr): fObj(ptr) {}
  38.  
  39. void* GetObjectAddr() const final { return fObj.get(); }
  40.  
  41. const std::type_info& GetTypeInfo() const final { return typeid(T); }
  42.  
  43. private:
  44. std::shared_ptr<T> fObj;
  45.  
  46. void CastImpl() const final { throw fObj.get(); }
  47. };
  48.  
  49.  
  50. template <class T>
  51. string Find(const TDirectoryEntryPtrBase* ptr)
  52. {
  53. if (ptr->GetTypeInfo() == typeid(T))
  54. return "kValidValue";
  55. if (ptr->Cast<T>())
  56. return "kValidValueBase";
  57. return "kTypeMismatch";
  58. }
  59.  
  60.  
  61. class U/*nrelated*/ {};
  62. /* non-virtual */
  63. class B {};
  64. class D: public B {};
  65. /* virtual */
  66. class B_v {public: virtual ~B_v() {}};
  67. class D_v: public B_v {};
  68. /* deep hierarchy, non-virtual */
  69. class Top {};
  70. class Mid: public Top {};
  71. class Bot: public Mid {};
  72. /* deep hierarchy, virtual */
  73. class Top_v {public: virtual ~Top_v() {}};
  74. class Mid_v: public Top_v {};
  75. class Bot_v: public Mid_v {};
  76. /* multiple inheritance */
  77. class B1 {};
  78. class B2 {};
  79. class Dm: public B1, public B2 {};
  80. /* virtual base */
  81. class Bv1: public virtual B_v {};
  82. class Bv2: public virtual B_v {};
  83. class Dvm: public Bv1, public Bv2 {};
  84.  
  85.  
  86.  
  87. int main()
  88. {
  89. TDirectoryEntryPtr<D> d(new D);
  90. TDirectoryEntryPtr<B> b(new B);
  91. TDirectoryEntryPtr<D_v> d_v(new D_v);
  92. TDirectoryEntryPtr<B_v> b_v(new B_v);
  93.  
  94. TDirectoryEntryPtr<Top> top(new Top);
  95. TDirectoryEntryPtr<Mid> mid(new Mid);
  96. TDirectoryEntryPtr<Bot> bot(new Bot);
  97. TDirectoryEntryPtr<Top_v> top_v(new Top_v);
  98. TDirectoryEntryPtr<Mid_v> mid_v(new Mid_v);
  99. TDirectoryEntryPtr<Bot_v> bot_v(new Bot_v);
  100.  
  101. TDirectoryEntryPtr<B1> b1(new B1);
  102. TDirectoryEntryPtr<B2> b2(new B2);
  103. TDirectoryEntryPtr<Dm> dm(new Dm);
  104.  
  105. TDirectoryEntryPtr<Bv1> bv1(new Bv1);
  106. TDirectoryEntryPtr<Bv2> bv2(new Bv2);
  107. TDirectoryEntryPtr<Dvm> dvm(new Dvm);
  108.  
  109. cout << "Non-virtual:\n";
  110. cout << "Find<D>(d) [exact] " << Find<D>(&d) << endl;
  111. cout << "Find<B>(d) [upcast] " << Find<B>(&d) << endl;
  112. cout << "Find<D>(b) [downcast] " << Find<D>(&b) << endl;
  113. cout << "Find<B>(b) [exact] " << Find<B>(&b) << endl;
  114. cout << endl;
  115.  
  116. cout << "Virtual:\n";
  117. cout << "Find<D_v>(d_v) [exact] " << Find<D_v>(&d_v) << endl;
  118. cout << "Find<B_v>(d_v) [upcast] " << Find<B_v>(&d_v) << endl;
  119. cout << "Find<D_v>(b_v) [downcast] " << Find<D_v>(&b_v) << endl;
  120. cout << "Find<B_v>(b_v) [exact] " << Find<B_v>(&b_v) << endl;
  121. cout << endl;
  122.  
  123. cout << "Unrelated class:\n";
  124. cout << "Find<U>(d) " << Find<U>(&d) << endl;
  125. cout << "Find<U>(b) " << Find<U>(&b) << endl;
  126. cout << "Find<U>(d_v) " << Find<U>(&d_v) << endl;
  127. cout << "Find<U>(b_v) " << Find<U>(&b_v) << endl;
  128. cout << endl;
  129.  
  130. cout << "Deep hierarchy, non-virtual:\n";
  131. cout << "Find<Top>(top) [ 0 cast(s)] " << Find<Top>(&top) << endl;
  132. cout << "Find<Top>(mid) [ 1 cast(s)] " << Find<Top>(&mid) << endl;
  133. cout << "Find<Top>(bot) [ 2 cast(s)] " << Find<Top>(&bot) << endl;
  134. cout << "Find<Mid>(top) [-1 cast(s)] " << Find<Mid>(&top) << endl;
  135. cout << "Find<Mid>(mid) [ 0 cast(s)] " << Find<Mid>(&mid) << endl;
  136. cout << "Find<Mid>(bot) [ 1 cast(s)] " << Find<Mid>(&bot) << endl;
  137. cout << "Find<Bot>(top) [-2 cast(s)] " << Find<Bot>(&top) << endl;
  138. cout << "Find<Bot>(mid) [-1 cast(s)] " << Find<Bot>(&mid) << endl;
  139. cout << "Find<Bot>(bot) [ 0 cast(s)] " << Find<Bot>(&bot) << endl;
  140. cout << endl;
  141.  
  142. cout << "Deep hierarchy, virtual:\n";
  143. cout << "Find<Top_v>(top_v) [ 0 cast(s)] " << Find<Top_v>(&top_v) << endl;
  144. cout << "Find<Top_v>(mid_v) [ 1 cast(s)] " << Find<Top_v>(&mid_v) << endl;
  145. cout << "Find<Top_v>(bot_v) [ 2 cast(s)] " << Find<Top_v>(&bot_v) << endl;
  146. cout << "Find<Mid_v>(top_v) [-1 cast(s)] " << Find<Mid_v>(&top_v) << endl;
  147. cout << "Find<Mid_v>(mid_v) [ 0 cast(s)] " << Find<Mid_v>(&mid_v) << endl;
  148. cout << "Find<Mid_v>(bot_v) [ 1 cast(s)] " << Find<Mid_v>(&bot_v) << endl;
  149. cout << "Find<Bot_v>(top_v) [-2 cast(s)] " << Find<Bot_v>(&top_v) << endl;
  150. cout << "Find<Bot_v>(mid_v) [-1 cast(s)] " << Find<Bot_v>(&mid_v) << endl;
  151. cout << "Find<Bot_v>(bot_v) [ 0 cast(s)] " << Find<Bot_v>(&bot_v) << endl;
  152. cout << endl;
  153.  
  154. cout << "Multiple inheritance:\n";
  155. cout << "Find<B1>(dm) [upcast] " << Find<B1>(&dm) << endl;
  156. cout << "Find<B2>(dm) [upcast] " << Find<B2>(&dm) << endl;
  157. cout << "Find<B1>(b2) [sidecast] " << Find<B1>(&b2) << endl;
  158. cout << "Find<B2>(b1) [sidecast] " << Find<B2>(&b1) << endl;
  159. cout << endl;
  160.  
  161. cout << "Virtual base:\n";
  162. cout << "FInd<B_v>(dvm) [virtual base upcast] " << Find<B_v>(&dvm) << endl;
  163. cout << "FInd<B_v>(bv1) [virtual base upcast] " << Find<B_v>(&bv1) << endl;
  164. cout << "Find<B_v>(bv2) [virtual base upcast] " << Find<B_v>(&bv2) << endl;
  165. cout << "Find<Bv1>(bv1) [exact] " << Find<Bv1>(&bv1) << endl;
  166. cout << "Find<Bv2>(bv2) [exact] " << Find<Bv2>(&bv2) << endl;
  167. cout << "Find<Bv1>(dvm) [upcast] " << Find<Bv1>(&dvm) << endl;
  168. cout << "Find<Bv2>(dvm) [upcast] " << Find<Bv2>(&dvm) << endl;
  169. cout << "Find<Bv1>(bv2) [sidecast] " << Find<Bv1>(&bv2) << endl;
  170. cout << "Find<Bv2>(bv1) [sidecast] " << Find<Bv2>(&bv1) << endl;
  171. cout << endl;
  172. }
Success #stdin #stdout 0s 3496KB
stdin
Standard input is empty
stdout
Non-virtual:
Find<D>(d) [exact]    kValidValue
Find<B>(d) [upcast]   kValidValueBase
Find<D>(b) [downcast] kTypeMismatch
Find<B>(b) [exact]    kValidValue

Virtual:
Find<D_v>(d_v) [exact]    kValidValue
Find<B_v>(d_v) [upcast]   kValidValueBase
Find<D_v>(b_v) [downcast] kTypeMismatch
Find<B_v>(b_v) [exact]    kValidValue

Unrelated class:
Find<U>(d)   kTypeMismatch
Find<U>(b)   kTypeMismatch
Find<U>(d_v) kTypeMismatch
Find<U>(b_v) kTypeMismatch

Deep hierarchy, non-virtual:
Find<Top>(top) [ 0 cast(s)] kValidValue
Find<Top>(mid) [ 1 cast(s)] kValidValueBase
Find<Top>(bot) [ 2 cast(s)] kValidValueBase
Find<Mid>(top) [-1 cast(s)] kTypeMismatch
Find<Mid>(mid) [ 0 cast(s)] kValidValue
Find<Mid>(bot) [ 1 cast(s)] kValidValueBase
Find<Bot>(top) [-2 cast(s)] kTypeMismatch
Find<Bot>(mid) [-1 cast(s)] kTypeMismatch
Find<Bot>(bot) [ 0 cast(s)] kValidValue

Deep hierarchy, virtual:
Find<Top_v>(top_v) [ 0 cast(s)] kValidValue
Find<Top_v>(mid_v) [ 1 cast(s)] kValidValueBase
Find<Top_v>(bot_v) [ 2 cast(s)] kValidValueBase
Find<Mid_v>(top_v) [-1 cast(s)] kTypeMismatch
Find<Mid_v>(mid_v) [ 0 cast(s)] kValidValue
Find<Mid_v>(bot_v) [ 1 cast(s)] kValidValueBase
Find<Bot_v>(top_v) [-2 cast(s)] kTypeMismatch
Find<Bot_v>(mid_v) [-1 cast(s)] kTypeMismatch
Find<Bot_v>(bot_v) [ 0 cast(s)] kValidValue

Multiple inheritance:
Find<B1>(dm) [upcast]   kValidValueBase
Find<B2>(dm) [upcast]   kValidValueBase
Find<B1>(b2) [sidecast] kTypeMismatch
Find<B2>(b1) [sidecast] kTypeMismatch

Virtual base:
FInd<B_v>(dvm) [virtual base upcast] kValidValueBase
FInd<B_v>(bv1) [virtual base upcast] kValidValueBase
Find<B_v>(bv2) [virtual base upcast] kValidValueBase
Find<Bv1>(bv1) [exact]               kValidValue
Find<Bv2>(bv2) [exact]               kValidValue
Find<Bv1>(dvm) [upcast]              kValidValueBase
Find<Bv2>(dvm) [upcast]              kValidValueBase
Find<Bv1>(bv2) [sidecast]            kTypeMismatch
Find<Bv2>(bv1) [sidecast]            kTypeMismatch