Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

C++: dynamic type equation.

By: a guest on Jul 27th, 2012  |  syntax: C++  |  size: 4.15 KB  |  views: 178  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <typeinfo>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <cxxabi.h>
  5. #include <assert.h>
  6.  
  7. class Object;
  8.  
  9. class Type {
  10. public:
  11.     Type(Object *object) : object(object) {
  12.     }
  13.    
  14.     Object *object;
  15.    
  16.     bool operator==(Type other);
  17.     bool operator!=(Type other);
  18.    
  19.     enum class LesserOperatorStatus {
  20.         Lesser = 0,
  21.         Equal = 1,
  22.         Object = 2,
  23.         Error = 3
  24.     };
  25.    
  26.     LesserOperatorStatus operator_lesser(const std::type_info &other_info);
  27.    
  28.     bool operator<(Type other);
  29.    
  30.     bool operator>(Type other);
  31.    
  32.     bool operator>=(Type other);
  33.    
  34.     bool operator<=(Type other);
  35. };
  36.  
  37. class Object {
  38. public:
  39.     virtual ~Object() {};
  40.     Type type() {
  41.         return Type(this);
  42.     }
  43. };
  44.  
  45. bool Type::operator==(Type other) {
  46.     return strcmp(typeid(*this->object).name(), typeid(*other.object).name()) == 0;
  47.     /*
  48.     std::type_info other_info = typeid(other.object);
  49.     const __cxxabiv1::__si_class_type_info* other__si_class_type_info = dynamic_cast<const __cxxabiv1::__si_class_type_info*>(&other_info);
  50.     assert(other__si_class_type_info);
  51.    
  52.     return (typeid(*this->object) == *other__si_class_type_info->__base_type);
  53.     */
  54. }
  55.  
  56. bool Type::operator!=(Type other) {
  57.     return !this->operator==(other);
  58. }
  59.  
  60. Type::LesserOperatorStatus Type::operator_lesser(const std::type_info &other_info) {
  61.     Type::LesserOperatorStatus result = LesserOperatorStatus::Error;
  62.    
  63.     if (typeid(*this->object) == other_info) {
  64.         result = LesserOperatorStatus::Equal;
  65.     } else {
  66.         const __cxxabiv1::__si_class_type_info* other__si_class_type_info = dynamic_cast<const __cxxabiv1::__si_class_type_info*>(&other_info);
  67.        
  68.        
  69.         if (!other__si_class_type_info) {
  70.             assert(0);
  71.             //printf("Assertion failed! this : %s, other : %s\n", typeid(*this->object).name(), other_info.name());
  72.             result = LesserOperatorStatus::Error;
  73.         } else {
  74.             const std::type_info *other_base_info = other__si_class_type_info->__base_type;
  75.            
  76.             if (typeid(*this->object) == *other_base_info) {
  77.                 result = LesserOperatorStatus::Lesser;
  78.             } else if (typeid(Object) == *other_base_info) {
  79.                 result = LesserOperatorStatus::Object;
  80.             } else {
  81.                 LesserOperatorStatus status = operator_lesser(*other_base_info);
  82.                 if (status == LesserOperatorStatus::Equal || status == LesserOperatorStatus::Lesser) {
  83.                     result = LesserOperatorStatus::Lesser;
  84.                 } else {
  85.                     result = status;
  86.                 }
  87.             }
  88.         }
  89.     }
  90.    
  91.     return result;
  92. }
  93.  
  94. bool Type::operator<(Type other) {
  95.     const std::type_info *other_info = &typeid(*other.object);
  96.     return this->operator_lesser(*other_info) == LesserOperatorStatus::Lesser;
  97. }
  98.  
  99. bool Type::operator>(Type other) {
  100.     return other.operator<(*this);
  101. }
  102.  
  103. bool Type::operator>=(Type other) {
  104.     return this->operator==(other) || this->operator>(other);
  105. }
  106.  
  107. bool Type::operator<=(Type other) {
  108.     return this->operator==(other) || this->operator<(other);
  109. }
  110.  
  111. class Base : public Object {
  112. public:
  113. };
  114.  
  115. class Derived : public Base {
  116. public:
  117. };
  118.  
  119. class Leaf : public Derived {
  120. public:
  121. };
  122.  
  123. class Another : public Object {
  124. public:
  125. };
  126.  
  127. int main() {
  128.     Object *objects[] = { new Base(), new Derived(), new Leaf(), new Another() };
  129.     size_t count = sizeof(objects) / sizeof(*objects);
  130.  
  131.     for (int i = 0; i < count; i++) {
  132.         for (int j = 0; j < count; j++) {
  133.             char trueStr[] = "\033[1;32mtrue\033[00m";
  134.             char falseStr[] = "\033[1;31mfalse\033[00m";;
  135.                        
  136.             #define testoperator(op) printf("%s " #op " %s | %s\n", &typeid(*objects[i]).name()[1], &typeid(*objects[j]).name()[1], (objects[i]->type() op objects[j]->type()) ? trueStr : falseStr)
  137.             testoperator(==);
  138.             testoperator(!=);
  139.             testoperator(<);
  140.             testoperator(>);
  141.             testoperator(<=);
  142.             testoperator(>=);
  143.             printf("\n");
  144.         }
  145.     }
  146. };