00001 #ifndef toast_typeinfo_hpp_INCLUDED 00002 #define toast_typeinfo_hpp_INCLUDED 00003 00004 #include <typeinfo> 00005 #include <string> 00006 #include <functional> 00007 00014 namespace toast { 00015 00036 class type_info 00037 { 00038 public: 00039 bool operator==(type_info const& rhs) const 00040 { 00041 std::less<type_info const *> l; 00042 return !(l(this, &rhs) || l(&rhs, this)); 00043 } 00044 bool operator!=(type_info const& rhs) const 00045 { 00046 return !(*this == rhs); 00047 } 00048 bool before(type_info const& rhs) const 00049 { 00050 if(*this == rhs) return false; 00051 return name() < rhs.name(); 00052 } 00053 std::string const & name() const 00054 { 00055 if(portable_name_.empty()) { 00056 portable_name_ = demangled_name(); 00057 } 00058 return portable_name_; 00059 } 00060 private: 00061 static type_info const & get(std::type_info const &std_info); 00062 00063 template <typename T> 00064 friend type_info const & type_id(); 00065 00066 template <typename T> 00067 friend type_info const & type_id(T const &t); 00068 00069 type_info(std::type_info const &t) : type_info_(t) {} 00070 type_info & operator=(const type_info &rhs); 00071 std::string demangled_name() const; 00072 00073 std::type_info const &type_info_; 00074 mutable std::string portable_name_; 00075 }; 00076 00078 template <typename T> 00079 type_info const & type_id() { 00080 return type_info::get(typeid(T)); 00081 } 00082 00084 template <typename T> 00085 type_info const & type_id(T const &t) { 00086 return type_info::get(typeid(t)); 00087 } 00088 00091 } 00092 00093 #endif // toast_typeinfo_hpp_INCLUDED 00094