#include <typeinfo>
#include <stdio.h>
#include <string.h>
#include <cxxabi.h>
#include <assert.h>
class Object;
class Type {
public:
Type(Object *object) : object(object) {
}
Object *object;
bool operator==(Type other);
bool operator!=(Type other);
enum class LesserOperatorStatus {
Lesser = 0,
Equal = 1,
Object = 2,
Error = 3
};
LesserOperatorStatus operator_lesser(const std::type_info &other_info);
bool operator<(Type other);
bool operator>(Type other);
bool operator>=(Type other);
bool operator<=(Type other);
};
class Object {
public:
virtual ~Object() {};
Type type() {
return Type(this);
}
};
bool Type::operator==(Type other) {
return strcmp(typeid(*this->object).name(), typeid(*other.object).name()) == 0;
/*
std::type_info other_info = typeid(other.object);
const __cxxabiv1::__si_class_type_info* other__si_class_type_info = dynamic_cast<const __cxxabiv1::__si_class_type_info*>(&other_info);
assert(other__si_class_type_info);
return (typeid(*this->object) == *other__si_class_type_info->__base_type);
*/
}
bool Type::operator!=(Type other) {
return !this->operator==(other);
}
Type::LesserOperatorStatus Type::operator_lesser(const std::type_info &other_info) {
Type::LesserOperatorStatus result = LesserOperatorStatus::Error;
if (typeid(*this->object) == other_info) {
result = LesserOperatorStatus::Equal;
} else {
const __cxxabiv1::__si_class_type_info* other__si_class_type_info = dynamic_cast<const __cxxabiv1::__si_class_type_info*>(&other_info);
if (!other__si_class_type_info) {
assert(0);
//printf("Assertion failed! this : %s, other : %s\n", typeid(*this->object).name(), other_info.name());
result = LesserOperatorStatus::Error;
} else {
const std::type_info *other_base_info = other__si_class_type_info->__base_type;
if (typeid(*this->object) == *other_base_info) {
result = LesserOperatorStatus::Lesser;
} else if (typeid(Object) == *other_base_info) {
result = LesserOperatorStatus::Object;
} else {
LesserOperatorStatus status = operator_lesser(*other_base_info);
if (status == LesserOperatorStatus::Equal || status == LesserOperatorStatus::Lesser) {
result = LesserOperatorStatus::Lesser;
} else {
result = status;
}
}
}
}
return result;
}
bool Type::operator<(Type other) {
const std::type_info *other_info = &typeid(*other.object);
return this->operator_lesser(*other_info) == LesserOperatorStatus::Lesser;
}
bool Type::operator>(Type other) {
return other.operator<(*this);
}
bool Type::operator>=(Type other) {
return this->operator==(other) || this->operator>(other);
}
bool Type::operator<=(Type other) {
return this->operator==(other) || this->operator<(other);
}
class Base : public Object {
public:
};
class Derived : public Base {
public:
};
class Leaf : public Derived {
public:
};
class Another : public Object {
public:
};
int main() {
Object *objects[] = { new Base(), new Derived(), new Leaf(), new Another() };
size_t count = sizeof(objects) / sizeof(*objects);
for (int i = 0; i < count; i++) {
for (int j = 0; j < count; j++) {
char trueStr[] = "\033[1;32mtrue\033[00m";
char falseStr[] = "\033[1;31mfalse\033[00m";;
#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)
testoperator(==);
testoperator(!=);
testoperator(<);
testoperator(>);
testoperator(<=);
testoperator(>=);
printf("\n");
}
}
};