Advertisement
Guest User

Untitled

a guest
Nov 2nd, 2012
214
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.36 KB | None | 0 0
  1. namespace ac
  2. {
  3.     /// \class Class
  4.     /// \brief Describes a class
  5.     ///
  6.     /// A simple class that describes another class.
  7.     ///
  8.     /// \author Miguel Martin
  9.     class Class
  10.     {
  11.     public:
  12.        
  13.         explicit Class(const char* name = 0)
  14.         : _name(name)
  15.         {
  16.         }
  17.        
  18.        
  19.         /// \return The name of the class
  20.         const char* getName() const
  21.         {
  22.             return _name;
  23.         }
  24.        
  25.        
  26.        
  27.         /// Compares two class objects to see if they are equal
  28.         /// \param c The class you wish to compare with
  29.         /// \return true if the two classes are equal
  30.         bool operator==(const Class& c) const
  31.         {
  32.             return (this == &c);
  33.         }
  34.        
  35.         /// Compares two class objects to see if they are equal
  36.         /// \param c The class you wish to compare with
  37.         /// \return true if the two classes are not equal
  38.         bool operator!=(const Class& c) const
  39.         {
  40.             return !operator==(c);
  41.         }
  42.        
  43.     private:
  44.        
  45.         /// The name of the class
  46.         const char* _name;
  47.     };
  48.    
  49.     /// Converts something to a string
  50. #   define AC_CONVERT_TO_STR(x) #x
  51.    
  52.    
  53.     /// Marks a class as identifiable
  54.     /// You must place this macro inside the class's defintion,
  55.     /// if you wish to identfy a class
  56.     ///
  57.     /// For example:
  58.     /// class Example
  59.     /// {
  60.     ///     AC_IDENTFIABLE(Example)
  61.     /// };
  62. #   define AC_IDENTIFIABLE(x) \
  63.     public:\
  64.         static const ac::Class& GetClass() \
  65.         { \
  66.             static const ac::Class instance(AC_CONVERT_TO_STR(x)); \
  67.             return instance; \
  68.         } \
  69.         \
  70.         virtual const ac::Class& getClass() const \
  71.         { \
  72.             return GetClass(); \
  73.         } \
  74.     private:
  75.  
  76.     namespace util
  77.     {
  78.         /// \struct ClassGetter
  79.         /// \brief A utility class that gets a class of an object
  80.         ///
  81.         /// This is used so that it can be overloaded with pointer types.
  82.         ///
  83.         /// \author Miguel Martin
  84.         template <typename T>
  85.         struct ClassGetter
  86.         {
  87.         public:
  88.            
  89.             static const Class& Get()
  90.             {
  91.                 return T::GetClass();
  92.             }
  93.            
  94.            
  95.             static const Class& Get(const T* obj)
  96.             {
  97.                 return obj->getClass();
  98.             }
  99.         };
  100.        
  101.         template <typename T>
  102.         struct ClassGetter <T*>
  103.         {
  104.         public:
  105.            
  106.             static const Class& Get()
  107.             {
  108.                 return T::GetClass();
  109.             }
  110.            
  111.             static const Class& Get(const T* obj)
  112.             {
  113.                 return obj->getClass();
  114.             }
  115.         };
  116.        
  117.         /// \note This may or may NOT work on every platform/compiler
  118.         /// \param obj A pointer to an object with a v-table
  119.         /// \return A pointer to the v-table of the object
  120.         void* get_vtable(void *obj)
  121.         {
  122.             return *(reinterpret_cast<void **>(obj));
  123.         }
  124.     }
  125.    
  126.     /// Compares two objects and tells whether they are from the same class
  127.     /// \param x The first object that you wish to compare with
  128.     /// \param y The second object that you wish to compare with
  129.     /// \return true if the two objects are of the same type
  130.     template <typename X, typename Y>
  131.     bool isSameType(const X& x, const Y& y)
  132.     {
  133.         return util::ClassGetter<X>::Get(x) == util::ClassGetter<Y>::Get(y);
  134.     }
  135.    
  136.    
  137.     /// Tells whether an object is a specific type
  138.     /// \tparam Type The type of class that you wish to check that an object is
  139.     /// \return true if the object is of the class Type
  140.     template <class Type, class T>
  141.     bool isType(const T& obj)
  142.     {
  143.         return util::ClassGetter<Type>::Get() == util::ClassGetter<T>::Get(obj);
  144.     }
  145.    
  146.    
  147.    
  148.     /// Compares two polymorphic objects to tell whether they are equal types
  149.     /// \note
  150.     /// If you have two objects, that do NOT declare the macro AC_IDENTIFIABLE in
  151.     /// their class defintion, then perhaps you would want to use this method.
  152.     /// This may or may NOT work on every platform/compiler.
  153.     /// \param obj1 The first object you wish to compare
  154.     /// \param obj2 The second object you wish to compare
  155.     /// \return true if the two objects are of the same type
  156.     bool isSameType(void* obj1, void* obj2)
  157.     {
  158.         return util::get_vtable(obj1) == util::get_vtable(obj2);
  159.     }
  160. }
  161.  
  162.     class Base
  163. {
  164.     AC_IDENTIFIABLE(Base)
  165. };
  166.  
  167. class Derived
  168.     : public Base
  169. {
  170.     AC_IDENTIFIABLE(Derived)
  171. };
  172.  
  173.  
  174. int main(int argc, char** argv)
  175. {
  176.     using namespace ac;
  177.    
  178.     Base* obj1 = new Derived;
  179.     Base* obj2 = new Derived;
  180.    
  181.     std::cout << std::boolalpha;
  182.     std::cout << "void* casts: " << isSameType((void*)obj1, (void*)obj2) << '\n';
  183.     std::cout << "is obj1 a Base ? " << isType<Base>(obj1) << '\n';
  184.     std::cout << "is obj2 a Derived ? " << isType<Derived>(obj2) << '\n';
  185.     std::cout << "are obj1 and obj2 from the same class? " << isSameType(obj1, obj2) << '\n';
  186.    
  187.    
  188.     delete obj1;
  189.     delete obj2;
  190.     return 0;
  191. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement