fork(1) download
  1. #include <utility>
  2. #include <iostream>
  3.  
  4. template<typename T>
  5. struct fast_castable_leaf {
  6. virtual T* do_fast_cast(T* unused=nullptr) { return nullptr; }
  7. virtual T const* do_fast_cast(T* unused=nullptr) const { return nullptr; }
  8. virtual ~fast_castable_leaf() {}
  9. };
  10. template<typename Tuple>
  11. struct fast_castable;
  12. template<template<typename...>class Tuple>
  13. struct fast_castable<Tuple<>> {
  14. virtual ~fast_castable() {}
  15. };
  16. template<template<typename...>class Tuple, typename T, typename... Ts>
  17. struct fast_castable<Tuple<T,Ts...>>:
  18. fast_castable_leaf<T>,
  19. fast_castable<Tuple<Ts...>>
  20. {};
  21. template<typename T> struct block_deduction { typedef T type; };
  22. template<typename T> using NoDeduction = typename block_deduction<T>::type;
  23. template<typename T>
  24. T* fast_cast( NoDeduction<fast_castable_leaf<T>>* src ) {
  25. return src->do_fast_cast();
  26. }
  27. template<typename T>
  28. T const* fast_cast( NoDeduction<fast_castable_leaf<T>> const* src ) {
  29. return src->do_fast_cast();
  30. }
  31.  
  32. template<typename T, typename D>
  33. struct fast_cast_allowed : std::integral_constant<bool,
  34. std::is_base_of<T,D>::value || std::is_same<T,D>::value
  35. > {};
  36.  
  37. template<typename D, typename B, typename Tuple>
  38. struct implement_fast_cast;
  39.  
  40. template<typename D, typename B, template<typename...>class Tuple>
  41. struct implement_fast_cast<D,B,Tuple<>> : B {};
  42. template<typename D, typename B, template<typename...>class Tuple, typename T, typename... Ts>
  43. struct implement_fast_cast<D,B,Tuple<T,Ts...>> : implement_fast_cast<D, B, Tuple<Ts...>> {
  44. private:
  45. D* do_cast_work(std::true_type) { return static_cast<D*>(this); }
  46. D const* do_cast_work(std::true_type) const { return static_cast<D const*>(this); }
  47. std::nullptr_t do_cast_work(std::false_type) { return nullptr; }
  48. std::nullptr_t do_cast_work(std::false_type) const { return nullptr; }
  49. public:
  50. T* do_fast_cast( T* unused = nullptr ) override { return do_cast_work( fast_cast_allowed<T,D>() ); }
  51. T const* do_fast_cast( T* unused = nullptr ) const override { return do_cast_work( fast_cast_allowed<T,D>() ); }
  52. };
  53.  
  54. struct Dog;
  55. struct Cat;
  56. struct Moose;
  57. template<typename...>struct Types {};
  58. typedef Types<Dog, Cat, Moose> Mammal_Types;
  59.  
  60. struct Mammal : fast_castable<Mammal_Types>
  61. {};
  62.  
  63. struct Cat : implement_fast_cast< Cat, Mammal, Mammal_Types >
  64. {};
  65.  
  66. int main() {
  67. Cat c;
  68. Mammal* m=&c;
  69. Cat* c2 = fast_cast<Cat>(m);
  70. Dog* d2 = fast_cast<Dog>(m);
  71. std::cout << c2 << "," << d2 << "\n";
  72. }
  73.  
Success #stdin #stdout 0s 3304KB
stdin
Standard input is empty
stdout
0xbfc96570,0