runtime_cast.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. //
  2. // Copyright (c) Chris Glover, 2016.
  3. //
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. //[type_index_runtime_cast_example
  9. /*`
  10. The following example shows that `runtime_cast` is able to find a valid pointer
  11. in various class hierarchies regardless of inheritance or type relation.
  12. Example works with and without RTTI."
  13. */
  14. #include <boost/type_index/runtime_cast.hpp>
  15. #include <iostream>
  16. struct A {
  17. BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(BOOST_TYPE_INDEX_NO_BASE_CLASS)
  18. virtual ~A()
  19. {}
  20. };
  21. struct B {
  22. BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(BOOST_TYPE_INDEX_NO_BASE_CLASS)
  23. virtual ~B()
  24. {}
  25. };
  26. struct C : A {
  27. BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS((A))
  28. };
  29. struct D : B {
  30. BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS((B))
  31. };
  32. struct E : C, D {
  33. BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS((C)(D))
  34. };
  35. int main() {
  36. C c;
  37. A* a = &c;
  38. if(C* cp = boost::typeindex::runtime_cast<C*>(a)) {
  39. std::cout << "Yes, a points to a C: "
  40. << a << "->" << cp << '\n';
  41. }
  42. else {
  43. std::cout << "Error: Expected a to point to a C" << '\n';
  44. }
  45. if(E* ce = boost::typeindex::runtime_cast<E*>(a)) {
  46. std::cout << "Error: Expected a to not points to an E: "
  47. << a << "->" << ce << '\n';
  48. }
  49. else {
  50. std::cout << "But, a does not point to an E" << '\n';
  51. }
  52. E e;
  53. C* cp2 = &e;
  54. if(D* dp = boost::typeindex::runtime_cast<D*>(cp2)) {
  55. std::cout << "Yes, we can cross-cast from a C* to a D* when we actually have an E: "
  56. << cp2 << "->" << dp << '\n';
  57. }
  58. else {
  59. std::cout << "Error: Expected cp to point to a D" << '\n';
  60. }
  61. /*`
  62. Alternatively, we can use runtime_pointer_cast so we don't need to specity the target as a pointer.
  63. This works for smart_ptr types too.
  64. */
  65. A* ap = &e;
  66. if(B* bp = boost::typeindex::runtime_pointer_cast<B>(ap)) {
  67. std::cout << "Yes, we can cross-cast and up-cast at the same time."
  68. << ap << "->" << bp << '\n';
  69. }
  70. else {
  71. std::cout << "Error: Expected ap to point to a B" << '\n';
  72. }
  73. return 0;
  74. }
  75. //] [/type_index_runtime_cast_example]