// @author : Rew Innhwan(rihwan) // @mail : rihwan@gmail.com (private mail) // @mail : rihwan@neople.co.kr (company mail) // @brief : I implement fast rtti system\n // another rtti system consume Big O(n)\n // but I made a Big O(1) time consuming system\n // with Bit And Operation #include #include #include typedef unsigned int size_type; // @brief first I make a Bit Position Template\n // this class use class inheritance hierarchy depth template struct bit_position { static const size_type BIT_START; static const size_type BIT_END; }; // @brief simple helper macros #ifndef REGISTER_ROOT_HIERARCHY #define REGISTER_ROOT_HIERARCHY(SiblingCount) \ const size_type bit_position<0>::BIT_START = 0; \ const size_type bit_position<0>::BIT_END = SiblingCount; #endif #ifndef REGISTER_HIERARCHY #define REGISTER_HIERARCHY(Depth, SiblingCount) \ const size_type bit_position::BIT_START = \ bit_position::BIT_END; \ const size_type bit_position::BIT_END = \ bit_position::BIT_START + SiblingCount; #endif // @brief I use std::bitset for class #ifndef REGISTER_SIGNATURE_TYPE #define REGISTER_SIGNATURE_TYPE(Depth) \ typedef std::bitset< bit_position::BIT_END > \ sign_type; #endif // first need to register class count REGISTER_ROOT_HIERARCHY(2); REGISTER_HIERARCHY(1, 2); REGISTER_HIERARCHY(2, 3); REGISTER_HIERARCHY(3, 3); REGISTER_HIERARCHY(4, 2); // second need to register sign_type REGISTER_SIGNATURE_TYPE(4); class signature_base { private: const sign_type* signature_; public: explicit signature_base(const sign_type* sign) : signature_(sign) {} const sign_type* get_signature() const { return signature_; } }; template struct object_signature { typedef typename T my_type; typedef typename T::base_type base_type; enum { DEPTH = object_signature::DEPTH + 1 }; static const size_type SIBLING_INDEX; static const sign_type SIBLING_BIT; static const size_type BIT_START; static const size_type BIT_END; static const sign_type SIGNATURE; }; template <> struct object_signature { enum { DEPTH = 0 }; static const size_type SIBLING_INDEX; static const sign_type SIBLING_BIT; static const size_type BIT_START; static const size_type BIT_END; static const sign_type SIGNATURE; }; #ifndef REGISTER_ROOT_CLASS #define REGISTER_ROOT_CLASS(MyClass, SiblingIndex) \ typedef object_signature< MyClass > MyClass##OST; \ const size_type object_signature< MyClass >::SIBLING_INDEX = \ SiblingIndex; \ const sign_type object_signature< MyClass >::SIBLING_BIT = \ (sign_type(1) << SiblingIndex); \ const size_type object_signature< MyClass >::BIT_START = \ bit_position< MyClass##OST::DEPTH >::BIT_START; \ const size_type object_signature< MyClass >::BIT_END = \ bit_position< MyClass##OST::DEPTH >::BIT_END; \ const sign_type object_signature< MyClass >::SIGNATURE = \ SIBLING_BIT; #endif #ifndef REGISTER_CLASS #define REGISTER_CLASS(MyClass, SiblingIndex) \ typedef object_signature< MyClass > MyClass##OST; \ const size_type object_signature< MyClass >::SIBLING_INDEX = \ SiblingIndex; \ const sign_type object_signature< MyClass >::SIBLING_BIT = \ (sign_type(1) << SiblingIndex); \ const size_type object_signature< MyClass >::BIT_START = \ bit_position< MyClass##OST::DEPTH >::BIT_START; \ const size_type object_signature< MyClass >::BIT_END = \ bit_position< MyClass##OST::DEPTH >::BIT_END; \ const sign_type object_signature< MyClass >::SIGNATURE = \ object_signature< MyClass##OST::base_type >::SIGNATURE | \ ( SIBLING_BIT << object_signature< MyClass >::BIT_START ); #endif // @brief type casting function\n // this cast function consume O(1) template T* cast(signature_base* ptr) { if (0 == ptr) return 0; else if (ptr->get_signature() == &object_signature< T >::SIGNATURE) return (T*)ptr; else { const sign_type& sign = *ptr->get_signature(); if ((sign & object_signature< T >::SIGNATURE) == object_signature< T >::SIGNATURE) { return (T*)ptr; } else return 0; } } template const T* cast(const signature_base* ptr) { if (0 == ptr) return 0; else if (ptr->get_signature() == &object_signature< T >::SIGNATURE) return (const T*)ptr; else { const sign_type& sign = *ptr->get_signature(); if ((sign & object_signature< T >::SIGNATURE) == object_signature< T >::SIGNATURE) { return (const T*)ptr; } else return 0; } } struct first1 : public signature_base { typedef signature_base base_type; first1() : base_type(&object_signature::SIGNATURE) {} explicit first1(const sign_type* sign) : base_type(sign) {} }; struct first2 : public signature_base { typedef signature_base base_type; first2() : base_type(&object_signature::SIGNATURE) {} explicit first2(const sign_type* sign) : base_type(sign) {} }; struct second1 : public first1 { typedef first1 base_type; second1() : base_type(&object_signature::SIGNATURE) {} explicit second1(const sign_type* sign) : base_type(sign) {} }; struct second2 : public first1 { typedef first1 base_type; second2() : base_type(&object_signature::SIGNATURE) {} explicit second2(const sign_type* sign) : base_type(sign) {} }; struct second3 : public first2 { typedef first2 base_type; second3() : base_type(&object_signature::SIGNATURE) {} explicit second3(const sign_type* sign) : base_type(sign) {} }; struct third1 : public second1 { typedef second1 base_type; third1() : base_type(&object_signature::SIGNATURE) {} explicit third1(const sign_type* sign) : base_type(sign) {} }; struct third2 : public second2 { typedef second2 base_type; third2() : base_type(&object_signature::SIGNATURE) {} explicit third2(const sign_type* sign) : base_type(sign) {} }; struct third3 : public second3 { typedef second3 base_type; third3() : base_type(&object_signature::SIGNATURE) {} explicit third3(const sign_type* sign) : base_type(sign) {} }; struct fourth1 : public third1 { typedef third1 base_type; fourth1() : base_type(&object_signature::SIGNATURE) {} explicit fourth1(const sign_type* sign) : base_type(sign) {} }; struct fourth2 : public third3 { typedef third3 base_type; fourth2() : base_type(&object_signature::SIGNATURE) {} explicit fourth2(const sign_type* sign) : base_type(sign) {} }; template void print_class_info(const T& obj) { using namespace std; cout << "Class Depth: " << object_signature< T >::DEPTH << endl; cout << "Sibling Index: " << object_signature< T >::SIBLING_INDEX << endl; cout << hex; ios_base::fmtflags before = cout.setf(ios_base::showbase); cout << "Sibling Bit: " << (1 << object_signature< T >::SIBLING_INDEX) << endl; cout.setf(before); cout << dec; cout << "Bit Start: " << object_signature< T >::BIT_START << endl; cout << "Bit End: " << object_signature< T >::BIT_END << endl; cout << "Sibling Bit: " << object_signature< T >::SIBLING_BIT << endl; cout << "Signature: " << object_signature< T >::SIGNATURE << endl << endl; } // Macro Arguments // 1. Class Type // 2. Sibling Class Index REGISTER_ROOT_CLASS(first1, 0) REGISTER_ROOT_CLASS(first2, 1) REGISTER_CLASS(second1, 0) REGISTER_CLASS(second2, 1) REGISTER_CLASS(second3, 2) REGISTER_CLASS(third1, 0) REGISTER_CLASS(third2, 1) REGISTER_CLASS(third3, 2) REGISTER_CLASS(fourth1, 0) REGISTER_CLASS(fourth2, 1) void print_rtti(signature_base* p_obj) { using namespace std; first1* p_cast_first1 = cast(p_obj); if (0 != p_cast_first1) cout << "p_obj is kind of first1" << endl; else cout << "p_obj is not kind of first1" << endl; first2* p_cast_first2 = cast(p_obj); if (0 != p_cast_first2) cout << "p_obj is kind of first2" << endl; else cout << "p_obj is not kind of first2" << endl; second1* p_cast_second1 = cast(p_obj); if (0 != p_cast_second1) cout << "p_obj is kind of second1" << endl; else cout << "p_obj is not kind of second1" << endl; second2* p_cast_second2 = cast(p_obj); if (0 != p_cast_second2) cout << "p_obj is kind of second2" << endl; else cout << "p_obj is not kind of second2" << endl; second3* p_cast_second3 = cast(p_obj); if (0 != p_cast_second3) cout << "p_obj is kind of second3" << endl; else cout << "p_obj is not kind of second3" << endl; third1* p_cast_third1 = cast(p_obj); if (0 != p_cast_third1) cout << "p_obj is kind of third1" << endl; else cout << "p_obj is not kind of third1" << endl; third2* p_cast_third2 = cast(p_obj); if (0 != p_cast_third2) cout << "p_obj is kind of third2" << endl; else cout << "p_obj is not kind of third2" << endl; third3* p_cast_third3 = cast(p_obj); if (0 != p_cast_third3) cout << "p_obj is kind of third3" << endl; else cout << "p_obj is not kind of third3" << endl; fourth1* p_cast_fourth1 = cast(p_obj); if (0 != p_cast_fourth1) cout << "p_obj is kind of fourth1" << endl; else cout << "p_obj is not kind of fourth1" << endl; fourth2* p_cast_fourth2 = cast(p_obj); if (0 != p_cast_fourth2) cout << "p_obj is kind of fourth2" << endl; else cout << "p_obj is not kind of fourth2" << endl; cout << endl; } int main(int argc, char* argv[]) { using namespace std; first1 my_first1; print_class_info(my_first1); first2 my_first2; print_class_info(my_first2); second1 my_second1; print_class_info(my_second1); second2 my_second2; print_class_info(my_second2); second3 my_second3; print_class_info(my_second3); third1 my_third1; print_class_info(my_third1); third2 my_third2; print_class_info(my_third2); third3 my_third3; print_class_info(my_third3); fourth1 my_fourth1; print_class_info(my_fourth1); fourth2 my_fourth2; print_class_info(my_fourth2); cout << endl; print_rtti(&my_first1); print_rtti(&my_first2); print_rtti(&my_second1); print_rtti(&my_second2); print_rtti(&my_second3); print_rtti(&my_third1); print_rtti(&my_third2); print_rtti(&my_third3); print_rtti(&my_fourth1); print_rtti(&my_fourth2); return 0; }